r220175 - CodeGen: ConstStructBuilder must verify packed constraints after padding

David Majnemer david.majnemer at gmail.com
Sun Oct 19 16:40:06 PDT 2014


Author: majnemer
Date: Sun Oct 19 18:40:06 2014
New Revision: 220175

URL: http://llvm.org/viewvc/llvm-project?rev=220175&view=rev
Log:
CodeGen: ConstStructBuilder must verify packed constraints after padding

This reverts commit r220169 which reverted r220153.  However, it also
contains additional changes:
- We may need to add padding *after* we've packed the struct.  This
  occurs when the aligned next field offset is greater than the new
  field's offset.  When this occurs, we make the struct packed.
  *However*, once packed the next field offset might be less than the
  new feild's offset.  It is in this case that we might further pad the
  struct.
- We would pad structs which were perfectly sized!  This behavior is
  immensely old.  This behavior came from blindly subtracting
  NextFieldOffsetInChars from RecordSize.  This doesn't take into
  account the fact that the struct might have a greater overall
  alignment than the last field.

Modified:
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c
    cfe/trunk/test/CodeGen/const-init.c
    cfe/trunk/test/CodeGenCXX/atomicinit.cpp
    cfe/trunk/test/CodeGenCXX/debug-info-template.cpp
    cfe/trunk/test/Modules/templates.mm

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=220175&r1=220174&r2=220175&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Sun Oct 19 18:40:06 2014
@@ -104,16 +104,7 @@ AppendBytes(CharUnits FieldOffsetInChars
 
   // Round up the field offset to the alignment of the field type.
   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;
-  }
+      NextFieldOffsetInChars.RoundUpToAlignment(FieldAlignment);
 
   if (AlignedNextFieldOffsetInChars < FieldOffsetInChars) {
     // We need to append padding.
@@ -122,6 +113,24 @@ AppendBytes(CharUnits FieldOffsetInChars
     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();
+
+    // After we pack the struct, we may need to insert padding.
+    if (NextFieldOffsetInChars < FieldOffsetInChars) {
+      // We need to append padding.
+      AppendPadding(FieldOffsetInChars - NextFieldOffsetInChars);
+
+      assert(NextFieldOffsetInChars == FieldOffsetInChars &&
+             "Did not add enough padding!");
+    }
     AlignedNextFieldOffsetInChars = NextFieldOffsetInChars;
   }
 
@@ -486,10 +495,14 @@ llvm::Constant *ConstStructBuilder::Fina
     // No tail padding is necessary.
   } else {
     // Append tail padding if necessary.
-    AppendTailPadding(LayoutSizeInChars);
-
     CharUnits LLVMSizeInChars =
-      NextFieldOffsetInChars.RoundUpToAlignment(LLVMStructAlignment);
+        NextFieldOffsetInChars.RoundUpToAlignment(LLVMStructAlignment);
+
+    if (LLVMSizeInChars != LayoutSizeInChars)
+      AppendTailPadding(LayoutSizeInChars);
+
+    LLVMSizeInChars =
+        NextFieldOffsetInChars.RoundUpToAlignment(LLVMStructAlignment);
 
     // Check if we need to convert the struct to a packed struct.
     if (NextFieldOffsetInChars <= LayoutSizeInChars &&
@@ -501,7 +514,10 @@ llvm::Constant *ConstStructBuilder::Fina
              "Converting to packed did not help!");
     }
 
-    assert(LayoutSizeInChars == NextFieldOffsetInChars &&
+    LLVMSizeInChars =
+        NextFieldOffsetInChars.RoundUpToAlignment(LLVMStructAlignment);
+
+    assert(LayoutSizeInChars == LLVMSizeInChars &&
            "Tail padding mismatch!");
   }
 

Modified: cfe/trunk/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c?rev=220175&r1=220174&r2=220175&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c (original)
+++ cfe/trunk/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c Sun Oct 19 18:40:06 2014
@@ -8,5 +8,4 @@ struct et7 {
   52, 
 };
 
-// CHECK: @yv7 = global 
-// CHECK: i8 52,
+// CHECK: @yv7 = global %struct.et7 { [0 x float] zeroinitializer, i8 52 }

Modified: cfe/trunk/test/CodeGen/const-init.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/const-init.c?rev=220175&r1=220174&r2=220175&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/const-init.c (original)
+++ cfe/trunk/test/CodeGen/const-init.c Sun Oct 19 18:40:06 2014
@@ -159,3 +159,25 @@ 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()
+}
+
+void g31() {
+#pragma pack(4)
+  static struct {
+    short a;
+    long x;
+    short z;
+  } a = {23122, -12312731, -312};
+#pragma pack()
+  // CHECK: @g31.a = internal global %struct.anon.2 { i16 23122, i32 -12312731, i16 -312 }, align 4
+}

Modified: cfe/trunk/test/CodeGenCXX/atomicinit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/atomicinit.cpp?rev=220175&r1=220174&r2=220175&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/atomicinit.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/atomicinit.cpp Sun Oct 19 18:40:06 2014
@@ -1,9 +1,9 @@
 // RUN: %clang_cc1 %s -emit-llvm -O1 -o - -triple=i686-apple-darwin9 -std=c++11 | FileCheck %s
 
-// CHECK-DAG: @_ZN7PR180978constant1aE = global {{.*}} { i16 1, i8 6, i8 undef }, align 4
-// CHECK-DAG: @_ZN7PR180978constant1bE = global {{.*}} { i16 2, i8 6, i8 undef }, align 4
-// CHECK-DAG: @_ZN7PR180978constant1cE = global {{.*}} { i16 3, i8 6, i8 undef }, align 4
-// CHECK-DAG: @_ZN7PR180978constant1yE = global {{.*}} { {{.*}} { i16 4, i8 6, i8 undef }, i32 5 }, align 4
+// CHECK-DAG: @_ZN7PR180978constant1aE = global { i16, i8 } { i16 1, i8 6 }, align 4
+// CHECK-DAG: @_ZN7PR180978constant1bE = global { i16, i8 } { i16 2, i8 6 }, align 4
+// CHECK-DAG: @_ZN7PR180978constant1cE = global { i16, i8 } { i16 3, i8 6 }, align 4
+// CHECK-DAG: @_ZN7PR180978constant1yE = global { { i16, i8 }, i32 } { { i16, i8 } { i16 4, i8 6 }, i32 5 }, align 4
 
 struct A {
   _Atomic(int) i;

Modified: cfe/trunk/test/CodeGenCXX/debug-info-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-template.cpp?rev=220175&r1=220174&r2=220175&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/debug-info-template.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/debug-info-template.cpp Sun Oct 19 18:40:06 2014
@@ -83,7 +83,7 @@
 
 // CHECK: metadata [[PTOARGS:![0-9]*]], metadata !"{{.*}}"} ; [ DW_TAG_structure_type ] [PaddingAtEndTemplate<&PaddedObj>]
 // CHECK: [[PTOARGS]] = metadata !{metadata [[PTOARG1:![0-9]*]]}
-// CHECK: [[PTOARG1]] = metadata !{metadata !"0x30\00\000\000", null, metadata [[CONST_PADDINGATEND_PTR:![0-9]*]], { i32, i8, [3 x i8] }* @PaddedObj, null} ; [ DW_TAG_template_value_parameter ]
+// CHECK: [[PTOARG1]] = metadata !{metadata !"0x30\00\000\000", null, metadata [[CONST_PADDINGATEND_PTR:![0-9]*]], %struct.PaddingAtEnd* @PaddedObj, null} ; [ DW_TAG_template_value_parameter ]
 // CHECK: [[CONST_PADDINGATEND_PTR]] = {{.*}} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from _ZTS12PaddingAtEnd]
 
 // CHECK: metadata !"[[TCNESTED]]", %"struct.TC<unsigned int, 2, &glb, &foo::e, &foo::f, &func, 1, 2, 3>::nested"* @tci, null} ; [ DW_TAG_variable ] [tci]

Modified: cfe/trunk/test/Modules/templates.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/templates.mm?rev=220175&r1=220174&r2=220175&view=diff
==============================================================================
--- cfe/trunk/test/Modules/templates.mm (original)
+++ cfe/trunk/test/Modules/templates.mm Sun Oct 19 18:40:06 2014
@@ -12,10 +12,10 @@ void testInlineRedeclEarly() {
 
 @import templates_right;
 
-// CHECK-DAG: @list_left = global { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 8,
-// CHECK-DAG: @list_right = global { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 12,
-// CHECK-DAG: @_ZZ15testMixedStructvE1l = {{.*}} constant { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 1,
-// CHECK-DAG: @_ZZ15testMixedStructvE1r = {{.*}} constant { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 2,
+// CHECK-DAG: @list_left = global %class.List { %"struct.List<int>::node"* null, i32 8 }, align 8
+// CHECK-DAG: @list_right = global %class.List { %"struct.List<int>::node"* null, i32 12 }, align 8
+// CHECK-DAG: @_ZZ15testMixedStructvE1l = {{.*}} constant %class.List { %{{.*}}* null, i32 1 }, align 8
+// CHECK-DAG: @_ZZ15testMixedStructvE1r = {{.*}} constant %class.List { %{{.*}}* null, i32 2 }, align 8
 // CHECK-DAG: @_ZN29WithUndefinedStaticDataMemberIA_iE9undefinedE = external global
 
 void testTemplateClasses() {





More information about the cfe-commits mailing list