diff options
| -rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 11 | ||||
| -rw-r--r-- | clang/test/CodeGen/sanitize-address-field-padding.cpp | 30 | 
2 files changed, 38 insertions, 3 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index d8966f888e4..72ccebd85c3 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -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) diff --git a/clang/test/CodeGen/sanitize-address-field-padding.cpp b/clang/test/CodeGen/sanitize-address-field-padding.cpp index 009605c92a4..5f049bb0058 100644 --- a/clang/test/CodeGen/sanitize-address-field-padding.cpp +++ b/clang/test/CodeGen/sanitize-address-field-padding.cpp @@ -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:  | 

