[cfe-commits] r89611 - in /cfe/trunk: lib/AST/RecordLayoutBuilder.cpp lib/AST/RecordLayoutBuilder.h test/SemaCXX/class-layout.cpp

Daniel Dunbar daniel at zuster.org
Sun Nov 22 11:54:54 PST 2009


Hi Anders,

Does this have to use an extra variable UnfilledBitsInLastByte? Can't
the code just round up DataSize once it is done laying out a single
class?

 - Daniel

On Sun, Nov 22, 2009 at 11:13 AM, Anders Carlsson <andersca at mac.com> wrote:
> Author: andersca
> Date: Sun Nov 22 13:13:51 2009
> New Revision: 89611
>
> URL: http://llvm.org/viewvc/llvm-project?rev=89611&view=rev
> Log:
> When laying out bitfields, make sure that the data size is always aligned to a byte. This fixes PR5580.
>
> Modified:
>    cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
>    cfe/trunk/lib/AST/RecordLayoutBuilder.h
>    cfe/trunk/test/SemaCXX/class-layout.cpp
>
> Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=89611&r1=89610&r2=89611&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
> +++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Sun Nov 22 13:13:51 2009
> @@ -22,9 +22,9 @@
>  using namespace clang;
>
>  ASTRecordLayoutBuilder::ASTRecordLayoutBuilder(ASTContext &Ctx)
> -  : Ctx(Ctx), Size(0), Alignment(8), Packed(false), MaxFieldAlignment(0),
> -  DataSize(0), IsUnion(false), NonVirtualSize(0), NonVirtualAlignment(8),
> -  PrimaryBase(0), PrimaryBaseWasVirtual(false) {}
> +  : Ctx(Ctx), Size(0), Alignment(8), Packed(false), UnfilledBitsInLastByte(0),
> +  MaxFieldAlignment(0), DataSize(0), IsUnion(false), NonVirtualSize(0),
> +  NonVirtualAlignment(8), PrimaryBase(0), PrimaryBaseWasVirtual(false) {}
>
>  /// LayoutVtable - Lay out the vtable and set PrimaryBase.
>  void ASTRecordLayoutBuilder::LayoutVtable(const CXXRecordDecl *RD) {
> @@ -521,7 +521,7 @@
>
>  void ASTRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
>   bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
> -  uint64_t FieldOffset = IsUnion ? 0 : DataSize;
> +  uint64_t FieldOffset = IsUnion ? 0 : (DataSize - UnfilledBitsInLastByte);
>   uint64_t FieldSize = D->getBitWidth()->EvaluateAsInt(Ctx).getZExtValue();
>
>   std::pair<uint64_t, unsigned> FieldInfo = Ctx.getTypeInfo(D->getType());
> @@ -549,14 +549,19 @@
>   // Place this field at the current location.
>   FieldOffsets.push_back(FieldOffset);
>
> -  // Reserve space for this field.
> -  if (IsUnion)
> -    Size = std::max(Size, FieldSize);
> -  else
> -    Size = FieldOffset + FieldSize;
> +  // Update DataSize to include the last byte containing (part of) the bitfield.
> +  if (IsUnion) {
> +    // FIXME: I think FieldSize should be TypeSize here.
> +    DataSize = std::max(DataSize, FieldSize);
> +  } else {
> +    uint64_t NewSizeInBits = FieldOffset + FieldSize;
> +
> +    DataSize = llvm::RoundUpToAlignment(NewSizeInBits, 8);
> +    UnfilledBitsInLastByte = DataSize - NewSizeInBits;
> +  }
>
> -  // Update the data size.
> -  DataSize = Size;
> +  // Update the size.
> +  Size = std::max(Size, DataSize);
>
>   // Remember max struct/class alignment.
>   UpdateAlignment(FieldAlign);
> @@ -568,6 +573,9 @@
>     return;
>   }
>
> +  // Reset the unfilled bits.
> +  UnfilledBitsInLastByte = 0;
> +
>   bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
>   uint64_t FieldOffset = IsUnion ? 0 : DataSize;
>   uint64_t FieldSize;
>
> Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.h?rev=89611&r1=89610&r2=89611&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/RecordLayoutBuilder.h (original)
> +++ cfe/trunk/lib/AST/RecordLayoutBuilder.h Sun Nov 22 13:13:51 2009
> @@ -27,12 +27,21 @@
>  class ASTRecordLayoutBuilder {
>   ASTContext &Ctx;
>
> +  /// Size - The current size of the record layout.
>   uint64_t Size;
> +
> +  /// Alignment - The current alignment of the record layout.
>   unsigned Alignment;
> +
>   llvm::SmallVector<uint64_t, 16> FieldOffsets;
>
>   /// Packed - Whether the record is packed or not.
>   bool Packed;
> +
> +  /// UnfilledBitsInLastByte - If the last field laid out was a bitfield,
> +  /// this contains the number of bits in the last byte that can be used for
> +  /// an adjacent bitfield if necessary.
> +  unsigned char UnfilledBitsInLastByte;
>
>   /// MaxFieldAlignment - The maximum allowed field alignment. This is set by
>   /// #pragma pack.
>
> Modified: cfe/trunk/test/SemaCXX/class-layout.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/class-layout.cpp?rev=89611&r1=89610&r2=89611&view=diff
>
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/class-layout.cpp (original)
> +++ cfe/trunk/test/SemaCXX/class-layout.cpp Sun Nov 22 13:13:51 2009
> @@ -47,3 +47,20 @@
>  struct H : G { };
>
>  SA(6, sizeof(H) == 1);
> +
> +// PR5580
> +namespace PR5580 {
> +
> +class A { bool iv0 : 1; };
> +SA(7, sizeof(A) == 1);
> +
> +class B : A { bool iv0 : 1; };
> +SA(8, sizeof(B) == 2);
> +
> +struct C { bool iv0 : 1; };
> +SA(9, sizeof(C) == 1);
> +
> +struct D : C { bool iv0 : 1; };
> +SA(10, sizeof(D) == 2);
> +
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>




More information about the cfe-commits mailing list