]> granicus.if.org Git - clang/commitdiff
fix -fsanitize-address-field-padding for the cases with virtual base classes
authorKostya Serebryany <kcc@google.com>
Fri, 17 Oct 2014 21:02:13 +0000 (21:02 +0000)
committerKostya Serebryany <kcc@google.com>
Fri, 17 Oct 2014 21:02:13 +0000 (21:02 +0000)
Summary: Correctly compute the non-virtual size of a class.

Test Plan: Build SPEC 2016 with -fsanitize-address-field-padding

Reviewers: rsmith

Reviewed By: rsmith

Subscribers: cfe-commits

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

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

lib/CodeGen/CGClass.cpp
test/CodeGen/sanitize-address-field-padding.cpp

index d31d50bb4b26c999248d1e7aa996a03d651c20cf..6f2c40af759e1a89e7eff227264c5834def1c9cf 100644 (file)
@@ -750,9 +750,7 @@ void CodeGenFunction::EmitAsanPrologueOrEpilogue(bool Prologue) {
 
   llvm::Value *ThisPtr = LoadCXXThis();
   ThisPtr = Builder.CreatePtrToInt(ThisPtr, IntPtrTy);
-  QualType RecordTy = Context.getTypeDeclType(ClassDecl);
-  uint64_t TypeSize = Context.getTypeSizeInChars(RecordTy).getQuantity();
-
+  uint64_t TypeSize = Info.getNonVirtualSize().getQuantity();
   // For each field check if it has sufficient padding,
   // if so (un)poison it with a call.
   for (size_t i = 0; i < SSV.size(); i++) {
index 42deb3a01bd9a52661c3cfea6069cc260215640d..009605c92a42631d6291284502ae89486c9066aa 100644 (file)
@@ -39,6 +39,23 @@ Positive1 positive1;
 // Positive1 with extra paddings
 // CHECK: type { i32, [12 x i8], i8, [15 x i8], i32, [12 x i8], [6 x i16], [12 x i8], i64, [8 x i8] }
 
+struct VirtualBase {
+  int foo;
+};
+
+class ClassWithVirtualBase : public virtual VirtualBase {
+ public:
+  ClassWithVirtualBase() {}
+  ~ClassWithVirtualBase() {}
+  int make_it_non_standard_layout;
+ private:
+  char x[7];
+  char y[9];
+};
+
+ClassWithVirtualBase class_with_virtual_base;
+
+
 class Negative1 {
  public:
   Negative1() {}
@@ -137,3 +154,12 @@ ExternCStruct extern_C_struct;
 // CHECK: call void @__asan_unpoison_intra_object_redzone({{.*}}8)
 // CHECK-NOT: __asan_unpoison_intra_object_redzone
 // CHECK: ret void
+//
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN20ClassWithVirtualBaseC1Ev
+// CHECK: call void @__asan_poison_intra_object_redzone({{.*}} 12)
+// CHECK: call void @__asan_poison_intra_object_redzone({{.*}} 9)
+// CHECK: call void @__asan_poison_intra_object_redzone({{.*}} 15)
+// CHECK-NOT: __asan_poison_intra_object_redzone
+// CHECK: ret void
+//