This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/77907] New: Add "const" to argument of constexpr constructor causes the object to be left in unconstructed state
- From: "freddie_chopin at op dot pl" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Sun, 09 Oct 2016 07:35:32 +0000
- Subject: [Bug c++/77907] New: Add "const" to argument of constexpr constructor causes the object to be left in unconstructed state
- Auto-submitted: auto-generated
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.