<html>
<head>
<base href="http://llvm.org/bugs/" />
</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 --- - [-cxx-abi microsoft] CodeGen expects incorrectly laid out structs"
href="http://llvm.org/bugs/show_bug.cgi?id=16655">16655</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>[-cxx-abi microsoft] CodeGen expects incorrectly laid out structs
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>unspecified
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Windows NT
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Keywords</th>
<td>ABI
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>LLVM Codegen
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>whunt@google.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvmbugs@cs.uiuc.edu
</td>
</tr>
<tr>
<th>Blocks</th>
<td>12477
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>After applying <a href="http://llvm-reviews.chandlerc.com/D1026">http://llvm-reviews.chandlerc.com/D1026</a> (fix MS C++ layout)
codgen is producing wrong symbols and constructor code for corrected layouts.
The issue stems from the distinction between vtables, vftables and vbtables.
For a simple test case:
namespace Test4 {
// Test reusing a vbptr from a non-virtual base.
struct A { int a; };
struct B : virtual A { int b; };
struct C : B, virtual A { int c; };
C c; // Force vbtable emission.
}
Pre-patch produced the following (incorrect) layout:
*** Dumping AST Record Layout
0 | struct Test4::A
0 | int a
| [sizeof=4, dsize=4, align=4
| nvsize=4, nvalign=4]
*** Dumping AST Record Layout
0 | struct Test4::B
0 | (B vtable pointer)
0 | (B vftable pointer)
4 | int b
8 | struct Test4::A (virtual base)
8 | int a
| [sizeof=12, dsize=12, align=4
| nvsize=8, nvalign=4]
Post patch produces the following (correct) layout:
*** Dumping AST Record Layout
0 | struct Test4::A
0 | int a
| [sizeof=4, dsize=4, align=4
| nvsize=4, nvalign=4]
*** Dumping AST Record Layout
0 | struct Test4::B
0 | (B vbtable pointer)
4 | int b
8 | struct Test4::A (virtual base)
8 | int a
| [sizeof=12, dsize=8, align=4
| nvsize=8, nvalign=4]
The major distinction is the label for the pointer. In the former layout there
is a vtable and a vftable both at 0, in the latter there's just a vbtable at 0.
This causes the types of the pointers to change.
Pre-patch layout:
Layout: <CGRecordLayout
LLVMType:%"struct.Test4::B" = type { i32 (...)**, i32, %"struct.Test4::A" }
NonVirtualBaseLLVMType:%"struct.Test4::B.base" = type { i32 (...)**, i32 }
IsZeroInitializable:1
BitFields:[
]>
Post-patch layout:
Layout: <CGRecordLayout
LLVMType:%"struct.Test4::B" = type { i32*, i32, %"struct.Test4::A" }
NonVirtualBaseLLVMType:%"struct.Test4::B.base" = type { i32*, i32 }
IsZeroInitializable:1
BitFields:[
]>
The change makes sense because a vfptr is a pointer to an array of function
pointers and a vbptr is a pointer to an array of integer offsets. However this
causes CodeGen to produce incorrect constructors and symbols:
Pre-patch (correct output)
@"\01??_8C@Test4@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0,
i32 12]
@"\01??_8B@Test4@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0,
i32 8]
Post-patch (incorrect output)
@"\01??_8C@Test4@@7B01@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32
0, i32 12]
@"\01??_8C@Test4@@7BB@1@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32
0, i32 12]
@"\01??_8B@Test4@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0,
i32 8]</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>