https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80431

            Bug ID: 80431
           Summary: Use of "this" pointer in member initializer causes
                    constructor not to be called (or ICE on gcc 7)
           Product: gcc
           Version: 6.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: edolstra at gmail dot com
  Target Milestone: ---

The following program is miscompiled by GCC 5.4.0 and 6.3.0:

=== start ===
extern "C" void puts(char const *);

struct Options { };

struct Option
{
    Option(Options * options)
    {
        puts("CREATE");
    }

    ~Option()
    {
        puts("DESTROY");
    }
};

struct MyOptions : Options { };

struct MyOptions2 : virtual MyOptions
{
    Option foo{this};
};

int main(int argc, char * * argv)
{
    MyOptions2 opts;
}
=== end ===

Running this prints:

$ g++ ./this-bug.cc
$ ./a.out 
DESTROY

That is, the constructor for the "foo" member is never executed, but the
destructor is. This appears to be caused by the combination of the use of a
virtual base class, and the use of a "this" pointer in the initializer.
Changing foo to:

    Option foo{(MyOptions*) this};

causes the constructor to run correctly:

$ ./a.out 
CREATE
DESTROY

Either variant works fine with Clang 3.9.1.

With GCC 7 (20170409 snapshot), the compiler gives an internal compiler error:

$ g++ ./this-bug.cc
./this-bug.cc:1:17: warning: declaration of ‘void puts(const char*)’ conflicts
with built-in declaration ‘int puts(const char*)’
[-Wbuiltin-declaration-mismatch]
 extern "C" void puts(char const *);
                 ^~~~
./this-bug.cc: In constructor ‘MyOptions2::MyOptions2()’:
./this-bug.cc:20:8: internal compiler error: tree check: expected class ‘type’,
have ‘exceptional’ (error_mark) in useless_type_conversion_p, at
gimple-expr.c:84
 struct MyOptions2 : virtual MyOptions
        ^~~~~~~~~~
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://gcc.gnu.org/bugs/> for instructions.

Tested on x86_64-linux (NixOS). Compiler info:

$ g++ -v
Using built-in specs.
COLLECT_GCC=/nix/store/mw03k1hhagbp2lnaa76k9gb8r9ha30gf-gcc-6.3.0/bin/g++
COLLECT_LTO_WRAPPER=/nix/store/mw03k1hhagbp2lnaa76k9gb8r9ha30gf-gcc-6.3.0/libexec/gcc/x86_64-pc-linux-gnu/6.3.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: 
Thread model: posix
gcc version 6.3.0 (GCC)

Reply via email to