const ASTRecordLayout &Layout =
CGF.getContext().getASTRecordLayout(Dtor->getParent());
- // Nothing to poison
- if(Layout.getFieldCount() == 0)
- return;
-
- // Construct pointer to region to begin poisoning, and calculate poison
- // size, so that only members declared in this class are poisoned.
- llvm::Value *OffsetPtr;
- CharUnits::QuantityType PoisonSize;
- ASTContext &Context = CGF.getContext();
-
- llvm::ConstantInt *OffsetSizePtr = llvm::ConstantInt::get(
- CGF.SizeTy, Context.toCharUnitsFromBits(Layout.getFieldOffset(0)).
- getQuantity());
-
- OffsetPtr = CGF.Builder.CreateGEP(CGF.Builder.CreateBitCast(
- CGF.LoadCXXThis(), CGF.Int8PtrTy), OffsetSizePtr);
-
- PoisonSize = Layout.getSize().getQuantity() -
- Context.toCharUnitsFromBits(Layout.getFieldOffset(0)).getQuantity();
-
llvm::Value *Args[] = {
- CGF.Builder.CreateBitCast(OffsetPtr, CGF.VoidPtrTy),
- llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
-
+ CGF.Builder.CreateBitCast(CGF.LoadCXXThis(), CGF.VoidPtrTy),
+ llvm::ConstantInt::get(CGF.SizeTy, Layout.getSize().getQuantity())};
llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy};
llvm::FunctionType *FnType =
llvm::Value *Fn =
CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
- // Disables tail call elimination, to prevent the current stack frame from
- // disappearing from the stack trace.
CGF.CurFn->addFnAttr("disable-tail-calls", "true");
CGF.EmitNounwindRuntimeCall(Fn, Args);
}
// the caller's body.
if (getLangOpts().AppleKext)
CurFn->addFnAttr(llvm::Attribute::AlwaysInline);
-
- // Insert memory-poisoning instrumentation, before final clean ups,
- // to ensure this class's members are protected from invalid access.
- if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor
- && SanOpts.has(SanitizerKind::Memory))
- EmitDtorSanitizerCallback(*this, Dtor);
-
break;
}
// Exit the try if applicable.
if (isTryBody)
ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true);
+
+ // Insert memory-poisoning instrumentation.
+ if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor
+ && SanOpts.has(SanitizerKind::Memory))
+ EmitDtorSanitizerCallback(*this, Dtor);
}
void CodeGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &Args) {
Simple s;
// Simple internal member is poisoned by compiler-generated dtor
// CHECK-LABEL: define {{.*}}SimpleD1Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
-// CHECK: call void {{.*}}SimpleD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
// CHECK-NOT: call void @__sanitizer_dtor_callback
// CHECK: ret void
Inlined i;
// Simple internal member is poisoned by compiler-generated dtor
// CHECK-LABEL: define {{.*}}InlinedD1Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
-// CHECK: call void {{.*}}InlinedD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
// CHECK-NOT: call void @__sanitizer_dtor_callback
// CHECK: ret void
// By including a Simple member in the struct, the compiler is
// forced to generate a non-trivial destructor.
// CHECK-LABEL: define {{.*}}Defaulted_Non_TrivialD1Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
-// CHECK: call void {{.*}}Defaulted_Non_TrivialD2
+// CHECK: call void @__sanitizer_dtor_callback
// CHECK-NOT: call void @__sanitizer_dtor_callback
// CHECK: ret void
+++ /dev/null
-// RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
-
-class Base {
- public:
- int x;
- Base() {
- x = 5;
- }
- virtual ~Base() {
- x += 1;
- }
-};
-
-class Derived : public Base {
- public:
- int y;
- Derived() {
- y = 10;
- }
- ~Derived() {
- y += 1;
- }
-};
-
-Derived d;
-
-// CHECK-LABEL: define {{.*}}DerivedD1Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
-// CHECK: call void {{.*}}DerivedD2Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
-// CHECK: ret void
-
-// CHECK-LABEL: define {{.*}}DerivedD0Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
-// CHECK: call void {{.*}}DerivedD1Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
-// CHECK: ret void
-
-// CHECK-LABEL: define {{.*}}BaseD1Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
-// CHECK: call void {{.*}}BaseD2Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
-// CHECK: ret void
-
-// CHECK-LABEL: define {{.*}}BaseD0Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
-// CHECK: call void {{.*}}BaseD1Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
-// CHECK: ret void
-
-// CHECK-LABEL: define {{.*}}BaseD2Ev
-// CHECK: call void @__sanitizer_dtor_callback
-// CHECK-NOT: call void @__sanitizer_dtor_callback
-// CHECK: ret void
-
-// CHECK-LABEL: define {{.*}}DerivedD2Ev
-// CHECK: call void @__sanitizer_dtor_callback
-// CHECK-NOT: call void @__sanitizer_dtor_callback
-// CHECK: call void {{.*}}BaseD2Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
-// CHECK: ret void
// Repressing the sanitization attribute results in no msan
// instrumentation of the destructor
// CHECK: define {{.*}}No_SanD1Ev{{.*}} [[ATTRIBUTE:#[0-9]+]]
-// CHECK-NOT: call void @__sanitizer_dtor_callback
// CHECK: call void {{.*}}No_SanD2Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback
// CHECK: ret void
// CHECK-ATTR: define {{.*}}No_SanD1Ev{{.*}} [[ATTRIBUTE:#[0-9]+]]
-// CHECK-ATTR-NOT: call void @__sanitizer_dtor_callback
// CHECK-ATTR: call void {{.*}}No_SanD2Ev
// CHECK-ATTR-NOT: call void @__sanitizer_dtor_callback
// CHECK-ATTR: ret void
// CHECK: define {{.*}}No_SanD2Ev{{.*}} [[ATTRIBUTE:#[0-9]+]]
-// CHECK: call void @__sanitizer_dtor_callback
-// CHECK-NOT: call void @__sanitizer_dtor_callback
// CHECK: call void {{.*}}Vector
-// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback
// CHECK: ret void
// CHECK-ATTR: define {{.*}}No_SanD2Ev{{.*}} [[ATTRIBUTE:#[0-9]+]]
-// CHECK-ATTR-NOT: call void @__sanitizer_dtor_callback
// CHECK-ATTR: call void {{.*}}Vector
// CHECK-ATTR-NOT: call void @__sanitizer_dtor_callback
// CHECK-ATTR: ret void