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

            Bug ID: 128098
           Summary: Delegating value-initialization incorrectly zeroes a
                    virtual base of a base subobject
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: yqtian668 at gmail dot com
  Target Milestone: ---
              Host: x86_64-pc-linux-gnu
            Target: x86_64-pc-linux-gnu
             Build: x86_64-pc-linux-gnu

GCC prints 0 after a delegating constructor value-initializes a base class
subobject. The program should print 42 because zero-initialization of a base
class subobject does not include its virtual base classes.

Testcase:

#include <cstdio>

struct A {
  int x = 42;
  virtual ~A() {}
};

struct B : virtual A {
  explicit B(int) : B() {}
  B() = default;
};

struct D : B {
  D() : B(0) {}
};

int main() {
  D d;
  std::printf("%d\n", d.x);
}

Command:

g++ -std=c++17 -O0 testcase.cpp && ./a.out

Actual behavior: GCC prints 0. The generated base-object constructor for B
clears storage belonging to the already-constructed virtual A base.

Expected behavior: The program should print 42. D constructs its virtual A base
before constructing its direct B base. The empty initializer in B(int) : B()
value-initializes the B base subobject. Because this B object is a base class
subobject, zero-initializing it must not zero-initialize its virtual A base.

The empty initializer in B(int) : B() value-initializes B. Because the
explicitly defaulted B() constructor is not user-provided, value-initialization
first zero-initializes the B object. However, this B object is a base class
subobject of D. Under [dcl.init]/5.3, zero-initialization of a base class
subobject does not include its virtual base classes. Therefore, this
initialization must not overwrite the A virtual base that D has already
constructed, and A::x must remain 42.

GCC 11.4.0 prints 42 for the same program. Clang trunk and Apple Clang 17 print
0.

Compiler version:

g++ (GCC) 17.0.0 20261021 (experimental)
GCC revision 8cc6e7178c2e3b6156d7992bd18285be0da3c92c
Target: x86_64-pc-linux-gnu

Reply via email to