Hi majnemer, rsmith,

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.

http://reviews.llvm.org/D5924

Files:
  lib/AST/RecordLayoutBuilder.cpp
  test/CodeGen/sanitize-address-field-padding.cpp
Index: lib/AST/RecordLayoutBuilder.cpp
===================================================================
--- lib/AST/RecordLayoutBuilder.cpp
+++ lib/AST/RecordLayoutBuilder.cpp
@@ -1645,6 +1645,11 @@
                   Context.toCharUnitsFromBits(UnpackedFieldAlign));
 }
 
+static bool fieldHasFlexibleArrayMember(const FieldDecl *FD) {
+  auto FieldRD = FD->getType()->getAsCXXRecordDecl();
+  return FieldRD && FieldRD->hasFlexibleArrayMember();
+}
+
 void RecordLayoutBuilder::LayoutField(const FieldDecl *D,
                                       bool InsertExtraPadding) {
   if (D->isBitField()) {
@@ -1750,7 +1755,8 @@
                       Context.toBits(UnpackedFieldOffset),
                       Context.toBits(UnpackedFieldAlign), FieldPacked, D);
 
-  if (InsertExtraPadding && !FieldSize.isZero()) {
+  if (InsertExtraPadding && !FieldSize.isZero() &&
+      !fieldHasFlexibleArrayMember(D)) {
     CharUnits ASanAlignment = CharUnits::fromQuantity(8);
     CharUnits ExtraSizeForAsan = ASanAlignment;
     if (FieldSize % ASanAlignment)
Index: test/CodeGen/sanitize-address-field-padding.cpp
===================================================================
--- test/CodeGen/sanitize-address-field-padding.cpp
+++ test/CodeGen/sanitize-address-field-padding.cpp
@@ -55,6 +55,28 @@
 
 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 Negative1 {
  public:
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to