]> granicus.if.org Git - clang/commitdiff
Fixed an assertion failure related to bitfield lowering.
authorWarren Hunt <whunt@google.com>
Sat, 1 Mar 2014 00:38:40 +0000 (00:38 +0000)
committerWarren Hunt <whunt@google.com>
Sat, 1 Mar 2014 00:38:40 +0000 (00:38 +0000)
When lowering a bitfield, CGRecordLowering would assign the wrong
storage type to a bitfield in some cases and trigger an assertion.  In
these cases the layout was still correct, just the bitfield info was
wrong.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@202562 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGRecordLayoutBuilder.cpp
test/CodeGen/union.c

index dd4c0cdb6b68af15e1bcef5aec00d65b346cb876..651436164177b1f05a790887f4d60238e55128d7 100644 (file)
@@ -277,6 +277,7 @@ void CGRecordLowering::lower(bool NVBaseType) {
 }
 
 void CGRecordLowering::lowerUnion() {
+  CharUnits LayoutSize = Layout.getSize();
   llvm::Type *StorageType = 0;
   // Compute zero-initializable status.
   if (!D->field_empty() && !isZeroInitializable(*D->field_begin()))
@@ -293,7 +294,10 @@ void CGRecordLowering::lowerUnion() {
       // Skip 0 sized bitfields.
       if (Field->getBitWidthValue(Context) == 0)
         continue;
-      setBitFieldInfo(*Field, CharUnits::Zero(), getStorageType(*Field));
+      llvm::Type *FieldType = getStorageType(*Field);
+      if (LayoutSize < getSize(FieldType))
+        FieldType = getByteArrayType(LayoutSize);
+      setBitFieldInfo(*Field, CharUnits::Zero(), FieldType);
     }
     Fields[*Field] = 0;
     llvm::Type *FieldType = getStorageType(*Field);
@@ -304,7 +308,6 @@ void CGRecordLowering::lowerUnion() {
         getSize(FieldType) > getSize(StorageType)))
       StorageType = FieldType;
   }
-  CharUnits LayoutSize = Layout.getSize();
   // If we have no storage type just pad to the appropriate size and return.
   if (!StorageType)
     return appendPaddingBytes(LayoutSize);
index 5c89e2d72a7e50c6de21e10271d0a8beb01f9e9d..730218210213d2fccc242bf99c97cc34c32e69aa 100644 (file)
@@ -44,3 +44,16 @@ typedef union T0 { unsigned int : 0; } T0;
 T0 t0;
 
 union { int large_bitfield: 31; char c } u2;
+
+struct dt_t_s {
+  union {
+    long long u : 56;
+  } __attribute__((packed));
+};
+struct {
+  struct {
+    struct {
+      struct dt_t_s t;
+    };
+  };
+} a;