http://llvm.org/bugs/show_bug.cgi?id=16655

            Bug ID: 16655
           Summary: [-cxx-abi microsoft] CodeGen expects incorrectly laid
                    out structs
           Product: clang
           Version: unspecified
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Keywords: ABI
          Severity: normal
          Priority: P
         Component: LLVM Codegen
          Assignee: [email protected]
          Reporter: [email protected]
                CC: [email protected]
            Blocks: 12477
    Classification: Unclassified

After applying http://llvm-reviews.chandlerc.com/D1026 (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]

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
LLVMbugs mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/llvmbugs

Reply via email to