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