This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/77907] New: Add "const" to argument of constexpr constructor causes the object to be left in unconstructed state


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.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]