<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>