[llvm-bugs] [Bug 33425] New: dynamic_cast from one virtual base to another produces the wrong answer

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Jun 12 12:21:08 PDT 2017


            Bug ID: 33425
           Summary: dynamic_cast from one virtual base to another produces
                    the wrong answer
           Product: new-bugs
           Version: trunk
          Hardware: PC
                OS: MacOS X
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: arthur.j.odwyer at gmail.com
                CC: llvm-bugs at lists.llvm.org

Consider this class hierarchy (sorry for the autogenerated names):

    #include <stdio.h>

    struct Class3 { virtual ~Class3() {} };
    struct Class5 : protected virtual Class3 {};
    struct Class6 : public virtual Class5 {};
    struct Class7 : public virtual Class3 {};
    struct Class9 : public Class6, public Class7 {};

    int main() {
        Class9 c;
        Class3 *subobj = static_cast<Class3 *>(&c);
        printf("cast Class3 to Class3: %p\n", dynamic_cast<Class3 *>(subobj));
        printf("cast Class3 to Class5: %p\n", dynamic_cast<Class5 *>(subobj));
        printf("cast Class3 to Class6: %p\n", dynamic_cast<Class6 *>(subobj));
        printf("cast Class3 to Class7: %p\n", dynamic_cast<Class7 *>(subobj));
        printf("cast Class3 to Class9: %p\n", dynamic_cast<Class9 *>(subobj));

[On Wandbox, Clang and GCC produce different results for this
code](https://wandbox.org/permlink/VAo2a5uwzJ3ifxG2): the cast from virtual
base `Class3` to non-virtual base `Class6` fails on Clang but succeeds on GCC.

I *think* that GCC is correct and Clang 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.

The weird thing is that Clang agrees with GCC that the cast to `Class5` ought
to succeed.

MSVC seems to agree with me and GCC.

You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20170612/5e73bf9f/attachment.html>

More information about the llvm-bugs mailing list