]> granicus.if.org Git - clang/commitdiff
CodeGen: ConstStructBuilder must verify packed constraints after padding
authorDavid Majnemer <david.majnemer@gmail.com>
Sun, 19 Oct 2014 00:03:10 +0000 (00:03 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sun, 19 Oct 2014 00:03:10 +0000 (00:03 +0000)
Before, ConstStructBuilder::AppendBytes would check packed constraints
prior to padding being added before the field's offset.  However, adding
this padding might force our struct to be packed.  Because we wouldn't
check *after* adding padding, ConstStructBuilder would be in an
inconsistent state leading to a crash.

This fixes PR21300.

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

lib/CodeGen/CGExprConstant.cpp
test/CodeGen/const-init.c

index 421e7deccc3917cb4309d938c9f0cbb41240fe3d..dd87dd4657e08edaab96b2fa9044b6414aa6bba7 100644 (file)
@@ -106,15 +106,6 @@ AppendBytes(CharUnits FieldOffsetInChars, llvm::Constant *InitCst) {
   CharUnits AlignedNextFieldOffsetInChars =
     NextFieldOffsetInChars.RoundUpToAlignment(FieldAlignment);
 
-  if (AlignedNextFieldOffsetInChars > FieldOffsetInChars) {
-    assert(!Packed && "Alignment is wrong even with a packed struct!");
-
-    // Convert the struct to a packed struct.
-    ConvertStructToPacked();
-
-    AlignedNextFieldOffsetInChars = NextFieldOffsetInChars;
-  }
-
   if (AlignedNextFieldOffsetInChars < FieldOffsetInChars) {
     // We need to append padding.
     AppendPadding(FieldOffsetInChars - NextFieldOffsetInChars);
@@ -122,6 +113,16 @@ AppendBytes(CharUnits FieldOffsetInChars, llvm::Constant *InitCst) {
     assert(NextFieldOffsetInChars == FieldOffsetInChars &&
            "Did not add enough padding!");
 
+    AlignedNextFieldOffsetInChars =
+      NextFieldOffsetInChars.RoundUpToAlignment(FieldAlignment);
+  }
+
+  if (AlignedNextFieldOffsetInChars > FieldOffsetInChars) {
+    assert(!Packed && "Alignment is wrong even with a packed struct!");
+
+    // Convert the struct to a packed struct.
+    ConvertStructToPacked();
+
     AlignedNextFieldOffsetInChars = NextFieldOffsetInChars;
   }
 
index 7d7ccae370dd91c2524ac24e018764f743fce8b2..ccc6604c4560c622e1a582a6e3b7eb5138925894 100644 (file)
@@ -159,3 +159,14 @@ void g29() {
   static int b[1] = { "asdf" }; // expected-warning {{incompatible pointer to integer conversion initializing 'int' with an expression of type 'char [5]'}}
   static int c[1] = { L"a" };
 }
+
+// PR21300
+void g30() {
+#pragma pack(1)
+  static struct {
+    int : 1;
+    int x;
+  } a = {};
+  // CHECK: @g30.a = internal global %struct.anon.1 <{ i8 undef, i32 0 }>, align 1
+#pragma pack()
+}