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*) { }