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

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
  -Wbase-conversion (C++, Objective-C++ only)
    Warn when a pointer/reference to an object is converted to a
    pointer/reference to a base class of the object and any intermediate
    base classes have not begun construction yet.

I think the [basic.life] reference I gave was incorrect. For an object under
construction the correct reference is [class.cdtor]. I'm no longer sure if the
original testcase is actually undefined, but both f(this) calls in this version
require an undefined conversion to B* before the D base class has begun
construction:

struct B { B(int) { } };
struct D : virtual B { D(int i) : B(i) { } };

int foo(B*) { return 0; }

struct X : D {
  X() : B(foo(this)), D(foo(this)) { }
};

int main() {
  X x;
}


The problem isn't specific to virtual bases either, this is also undefined
because it converts X* to B* before construction of the D base has begun:

struct B { };
struct D : B { D(int i) { } };

int foo(B*) { return 0; }

struct X : D {
  X() : D(foo(this)) { }
};

int main() {
  X x;
}

This testcase is based on the one in [class.cdtor] and doesn't give a warning
or ubsan error for the undefined E* to A* conversion:

struct A { };
struct B : virtual A { };
struct C : B { };
struct D : virtual A { D(A*); };
struct X { X(A*); };

struct E : C, D, X {
  E()
  : D(this), // undefined: upcast from E* to A* might use path E* → D* → A*
             // but D is not constructed
             // “D((C*)this)” would be defined:
             // E* → C* is defined because E() has started,
             // and C* → A* is defined because C is fully constructed

    X(this)  // defined: upon construction of X, C/B/D/A sublattice is
             // fully constructed
  { }
};

int main()
{
  E e;
}

D::D(A*) { }
X::X(A*) { }

Reply via email to