]> granicus.if.org Git - clang/commitdiff
Do not insert asan paddings after fields that have flexible arrays.
authorKostya Serebryany <kcc@google.com>
Mon, 27 Oct 2014 19:34:10 +0000 (19:34 +0000)
committerKostya Serebryany <kcc@google.com>
Mon, 27 Oct 2014 19:34:10 +0000 (19:34 +0000)
Summary:
We should avoid a tail padding not only if the last field
has zero size but also if the last field is a struct with a flexible array.

If/when http://reviews.llvm.org/D5478 is committed,
this will also handle the case of structs with zero-sized arrays.

Reviewers: majnemer, rsmith

Reviewed By: rsmith

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D5924

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

lib/AST/RecordLayoutBuilder.cpp
test/CodeGen/sanitize-address-field-padding.cpp

index d8966f888e476e13532d67d024f014a2d69633fc..72ccebd85c3de1c039bf7520e070bb5faeae271f 100644 (file)
@@ -1331,8 +1331,13 @@ void RecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
   // Layout each field, for now, just sequentially, respecting alignment.  In
   // the future, this will need to be tweakable by targets.
   bool InsertExtraPadding = D->mayInsertExtraPadding(/*EmitRemark=*/true);
-  for (const auto *Field : D->fields())
-    LayoutField(Field, InsertExtraPadding);
+  bool HasFlexibleArrayMember = D->hasFlexibleArrayMember();
+  for (auto I = D->field_begin(), End = D->field_end(); I != End; ++I) {
+    auto Next(I);
+    ++Next;
+    LayoutField(*I,
+                InsertExtraPadding && (Next != End || !HasFlexibleArrayMember));
+  }
 }
 
 // Rounds the specified size to have it a multiple of the char size.
@@ -1750,7 +1755,7 @@ void RecordLayoutBuilder::LayoutField(const FieldDecl *D,
                       Context.toBits(UnpackedFieldOffset),
                       Context.toBits(UnpackedFieldAlign), FieldPacked, D);
 
-  if (InsertExtraPadding && !FieldSize.isZero()) {
+  if (InsertExtraPadding) {
     CharUnits ASanAlignment = CharUnits::fromQuantity(8);
     CharUnits ExtraSizeForAsan = ASanAlignment;
     if (FieldSize % ASanAlignment)
index 009605c92a42631d6291284502ae89486c9066aa..5f049bb005890d52ac103d7b98deded5b874f240 100644 (file)
@@ -55,6 +55,36 @@ class ClassWithVirtualBase : public virtual VirtualBase {
 
 ClassWithVirtualBase class_with_virtual_base;
 
+class WithFlexibleArray1 {
+ public:
+  WithFlexibleArray1() {}
+  ~WithFlexibleArray1() {}
+  int make_it_non_standard_layout;
+ private:
+  char private1[33];
+  int flexible[];  // Don't insert padding after this field.
+};
+
+WithFlexibleArray1 with_flexible_array1;
+// CHECK: %class.WithFlexibleArray1 = type { i32, [12 x i8], [33 x i8], [15 x i8], [0 x i32] }
+
+class WithFlexibleArray2 {
+ public:
+  char x[21];
+  WithFlexibleArray1 flex1;  // Don't insert padding after this field.
+};
+
+WithFlexibleArray2 with_flexible_array2;
+// CHECK: %class.WithFlexibleArray2 = type { [21 x i8], [11 x i8], %class.WithFlexibleArray1 }
+
+class WithFlexibleArray3 {
+ public:
+  char x[13];
+  WithFlexibleArray2 flex2;  // Don't insert padding after this field.
+};
+
+WithFlexibleArray3 with_flexible_array3;
+
 
 class Negative1 {
  public: