[cfe-dev] Implementation of the CGRecordLayoutBuilder for Microsoft ABI.

John McCall rjmccall at apple.com
Fri Sep 23 11:44:21 PDT 2011


On Sep 23, 2011, at 5:30 AM, r4start wrote:
> I am writing CGRecordLayoutBuilder for Microsoft ABI and I have a problem.
> I have the following code for testing http://pastebin.com/27U2hcDC .
> 
> When generated layout for a class C, I have break assert in 
> CGRecordLayoutBuilder.cpp line 968
> assert(TypeSizeInBits == getTargetData().getTypeAllocSizeInBits(Ty) &&
>          "Type size mismatch!");.
> During debugging, I discovered that TypeSizeInBits smaller 
> getTargetData().getTypeAllocSizeInBits(Ty)  4 bytes.
> After investigation, I discovered that the alignment is added in 
> StructLayout constructor (TargetData.cpp line 73)
> // Add padding to the end of the struct so that it could be put in an array
>  // and all array elements would be aligned correctly.
>   if ((StructSize & (StructAlignment-1)) != 0)
>     StructSize = TargetData::RoundUpAlignment(StructSize, StructAlignment);
> 
> But this alignment is not necessary for class C.
> MSVC doesn't add to the end of the class alignment, if it has a virtual 
> base classes.
> I see two solutions to this problem:
>  1. Rewrite assert like this
>      (pseudocode)
>      if ABI == Microsoft && Class has virtual basses
>        assert(TypeSizeInBits == 
> (getTargetData().getTypeAllocSizeInBits(Ty) - 32) &&
>                     "Type size mismatch!");
>       else
>         old version;
>   2. Provide to StructLyout information about ABI.
> 
> I think the first way is more simple.

No.  A *lot* of downstream code will be broken if LLVM doesn't lay
out the IR type the way we think it's laid out, and that includes the
presence or absence of tail padding.

I don't see how this is possible, though.  Can you run through an
example?  What's the size and layout of class B here?

class A {
  char c;
};

class B : public virtual A {
  void *p;
};

I would expect that sizeof(B) is 12, and that it's laid out like this:
  [0-3] virtual base pointer
  [4-7] B.p
    [8] A.c
 [9-11] tail padding

Or are we talking about the base-subobject struct type?  It shouldn't
matter whether that type gets tail padding or not, because it's never
separately allocated.

John.



More information about the cfe-dev mailing list