https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81078
Bug ID: 81078 Summary: dynamic_cast to virtual base produces the wrong answer Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: arthur.j.odwyer at gmail dot com Target Milestone: --- (This was found by the same fuzzer as https://bugs.llvm.org/show_bug.cgi?id=33425 --- except in this case Clang gets the right answer and GCC gets it wrong.) #include <stdio.h> struct Class2 { virtual ~Class2() {} }; struct Class3 { virtual ~Class3() {} }; struct Class4 : protected virtual Class3, public Class2 {}; struct Class8 : public virtual Class3, public Class4 {}; int main() { Class8 c8; Class2 *c2 = static_cast<Class2 *>(&c8); Class3 *c3 = static_cast<Class3 *>(&c8); printf("cast Class3 to Class2: %p\n", dynamic_cast<Class2 *>(c3)); printf("cast Class2 to Class3: %p\n", dynamic_cast<Class3 *>(c2)); } Clang and GCC disagree about this code: Clang makes both dynamic_casts succeed, and GCC makes them both fail (that is, return nullptr). I believe that Clang is correct and GCC is wrong, because this case is covered by N4618 [expr.dynamic.cast] 5.2.7 /(8.2): > If C is the class type to which T points or refers, the runtime check > logically executes as follows: > > (8.1) If, in the most derived object pointed (referred) to by v, v points > (refers) to a public base class subobject of a C object, and if only one > object of type C is derived from the subobject pointed (referred) to by v the > result points (refers) to that C object. > > (8.2) Otherwise, if v points (refers) to a public base class subobject of the > most derived object, and the type of the most derived object has a base > class, of type C, that is unambiguous and public, the result points (refers) > to the C subobject of the most derived object. > > (8.3) Otherwise, the runtime check fails. MSVC seems to agree with me and with Clang.