[Bug c++/81078] New: dynamic_cast to virtual base produces the wrong answer

arthur.j.odwyer at gmail dot com gcc-bugzilla@gcc.gnu.org
Mon Jun 12 23:39:00 GMT 2017


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.


More information about the Gcc-bugs mailing list