summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2014-10-27 19:34:10 +0000
committerKostya Serebryany <kcc@google.com>2014-10-27 19:34:10 +0000
commit68c29da4c5a6e3f5443c3b2bfc0ee6d2f44002c8 (patch)
tree05caadf46f08fe3ea8eb742f9aedd478550c6571
parentaae76493f0d5d8c2858ea70f950366feb759d9ab (diff)
downloadbcm5719-llvm-68c29da4c5a6e3f5443c3b2bfc0ee6d2f44002c8.tar.gz
bcm5719-llvm-68c29da4c5a6e3f5443c3b2bfc0ee6d2f44002c8.zip
Do not insert asan paddings after fields that have flexible arrays.
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 llvm-svn: 220708
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp11
-rw-r--r--clang/test/CodeGen/sanitize-address-field-padding.cpp30
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:
OpenPOWER on IntegriCloud