<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - dynamic_cast from one virtual base to another produces the wrong answer"
   href="https://bugs.llvm.org/show_bug.cgi?id=33425">33425</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>dynamic_cast from one virtual base to another produces the wrong answer
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>MacOS X
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>new bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>arthur.j.odwyer@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>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](<a href="https://wandbox.org/permlink/VAo2a5uwzJ3ifxG2">https://wandbox.org/permlink/VAo2a5uwzJ3ifxG2</a>): 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):

<span class="quote">> If C is the class type to which T points or refers, the runtime check logically executes as follows:</span >
>
<span class="quote">> (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.</span >
>
<span class="quote">> (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.</span >
>
<span class="quote">> (8.3) Otherwise, the runtime check fails.</span >

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.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>