https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77907
Bug ID: 77907 Summary: Add "const" to argument of constexpr constructor causes the object to be left in unconstructed state Product: gcc Version: 6.2.0 Status: UNCONFIRMED Severity: critical Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: freddie_chopin at op dot pl Target Milestone: --- Target: x86_64-pc-linux-gnu, arm-none-eabi Failing test case: ------- 8< ------- 8< ------- 8< ------- 8< ------- 8< ------- 8< ------- $ cat test.cpp struct SomeClass { void someFunction() {} }; struct SomeFunctor { using MemberFunction = void(SomeClass::*)(); constexpr explicit SomeFunctor(const MemberFunction memberFunction) : memberFunction_{memberFunction} { } MemberFunction memberFunction_; }; extern SomeFunctor functor; SomeFunctor functor {&SomeClass::someFunction}; $ g++ test.cpp -c -O2 -std=c++11 $ objdump -SD --demangle test.o test.o: file format elf64-x86-64 Disassembly of section .bss: 0000000000000000 <functor>: ... Disassembly of section .comment: 0000000000000000 <.comment>: 0: 00 47 43 add %al,0x43(%rdi) 3: 43 3a 20 rex.XB cmp (%r8),%spl 6: 28 47 4e sub %al,0x4e(%rdi) 9: 55 push %rbp a: 29 20 sub %esp,(%rax) c: 36 2e 31 2e ss xor %ebp,%cs:(%rsi) 10: 31 20 xor %esp,(%rax) 12: 32 30 xor (%rax),%dh 14: 31 36 xor %esi,(%rsi) 16: 30 36 xor %dh,(%rsi) 18: 30 32 xor %dh,(%rdx) ... ------- 8< ------- 8< ------- 8< ------- 8< ------- 8< ------- 8< ------- As you can see the object get's placed in .bss section and no constructor is generated - the object will have only zeroes in the program. The thing that causes the problem here is the "const" added to the "memberFunction" argument of the constructor. If I remove it, then I get the properly constructed object in .data section. ------- 8< ------- 8< ------- 8< ------- 8< ------- 8< ------- 8< ------- $ cat test.cpp struct SomeClass { void someFunction() {} }; struct SomeFunctor { using MemberFunction = void(SomeClass::*)(); constexpr explicit SomeFunctor(/*const*/ MemberFunction memberFunction) : memberFunction_{memberFunction} { } MemberFunction memberFunction_; }; extern SomeFunctor functor; SomeFunctor functor {&SomeClass::someFunction}; $ g++ test.cpp -c -O2 -std=c++11 $ objdump -SD --demangle test.o test.o: file format elf64-x86-64 Disassembly of section .group: 0000000000000000 <.group>: 0: 01 00 add %eax,(%rax) 2: 00 00 add %al,(%rax) 4: 06 (bad) 5: 00 00 add %al,(%rax) ... Disassembly of section .data: 0000000000000000 <functor>: ... Disassembly of section .text._ZN9SomeClass12someFunctionEv: 0000000000000000 <SomeClass::someFunction()>: 0: f3 c3 repz retq Disassembly of section .comment: 0000000000000000 <.comment>: 0: 00 47 43 add %al,0x43(%rdi) 3: 43 3a 20 rex.XB cmp (%r8),%spl 6: 28 47 4e sub %al,0x4e(%rdi) 9: 55 push %rbp a: 29 20 sub %esp,(%rax) c: 36 2e 31 2e ss xor %ebp,%cs:(%rsi) 10: 31 20 xor %esp,(%rax) 12: 32 30 xor (%rax),%dh 14: 31 36 xor %esi,(%rsi) 16: 30 36 xor %dh,(%rsi) 18: 30 32 xor %dh,(%rdx) ... Disassembly of section .eh_frame: 0000000000000000 <.eh_frame>: 0: 14 00 adc $0x0,%al 2: 00 00 add %al,(%rax) 4: 00 00 add %al,(%rax) 6: 00 00 add %al,(%rax) 8: 01 7a 52 add %edi,0x52(%rdx) b: 00 01 add %al,(%rcx) d: 78 10 js 1f <.eh_frame+0x1f> f: 01 1b add %ebx,(%rbx) 11: 0c 07 or $0x7,%al 13: 08 90 01 00 00 14 or %dl,0x14000001(%rax) 19: 00 00 add %al,(%rax) 1b: 00 1c 00 add %bl,(%rax,%rax,1) 1e: 00 00 add %al,(%rax) 20: 00 00 add %al,(%rax) 22: 00 00 add %al,(%rax) 24: 02 00 add (%rax),%al ... ------- 8< ------- 8< ------- 8< ------- 8< ------- 8< ------- 8< ------- If I remove "constexpr" from the constructor then both cases work fine - object is placed in .bss, but object is constructed in generated _GLOBAL__sub_I_functor() startup function. The same code was working fine on GCC 5.3.1 for arm-none-eabi, now its failing for both x86_64-pc-linux-gnu and arm-none-eabi on GCC 6.2.0. The most problematic thing here is that there is no error, no warning, no nothing - the code is compiled, linked, etc. - it just doesn't work (as you imagine - due to nullptr dereferencing) as the objects are not constructed properly.