forked from OSchip/llvm-project
Basic code generation for MSan use-after-dtor.
Under the -fsanitize-memory-use-after-dtor (disabled by default) insert an MSan runtime library call at the end of every destructor. Patch by Naomi Musgrave. llvm-svn: 242097
This commit is contained in:
parent
2c4af3ead7
commit
7cacbe4d9e
|
@ -1357,6 +1357,25 @@ static bool CanSkipVTablePointerInitialization(ASTContext &Context,
|
|||
return true;
|
||||
}
|
||||
|
||||
// Generates function call for handling object poisoning, passing in
|
||||
// references to 'this' and its size as arguments.
|
||||
static void EmitDtorSanitizerCallback(CodeGenFunction &CGF,
|
||||
const CXXDestructorDecl *Dtor) {
|
||||
const ASTRecordLayout &Layout =
|
||||
CGF.getContext().getASTRecordLayout(Dtor->getParent());
|
||||
|
||||
llvm::Value *Args[] = {
|
||||
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::FunctionType::get(CGF.VoidTy, ArgTypes, false);
|
||||
llvm::Value *Fn =
|
||||
CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
|
||||
CGF.EmitNounwindRuntimeCall(Fn, Args);
|
||||
}
|
||||
|
||||
/// EmitDestructorBody - Emits the body of the current destructor.
|
||||
void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
|
||||
const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl());
|
||||
|
@ -1444,6 +1463,10 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
|
|||
// Exit the try if applicable.
|
||||
if (isTryBody)
|
||||
ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true);
|
||||
|
||||
// Insert memory-poisoning instrumentation.
|
||||
if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor)
|
||||
EmitDtorSanitizerCallback(*this, Dtor);
|
||||
}
|
||||
|
||||
void CodeGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &Args) {
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
// Test -fsanitize-memory-use-after-dtor
|
||||
// RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -fsanitize=memory -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s -check-prefix=NO_DTOR_CHECK
|
||||
|
||||
struct Simple {
|
||||
~Simple() {}
|
||||
};
|
||||
Simple s;
|
||||
// Simple internal member is poisoned by compiler-generated dtor
|
||||
// CHECK-LABEL: @_ZN6SimpleD2Ev
|
||||
// CHECK: call void @__sanitizer_dtor_callback
|
||||
// CHECK: ret void
|
||||
|
||||
// Compiling without the flag does not generate member-poisoning dtor
|
||||
// NO_DTOR_CHECK-LABEL: @_ZN6SimpleD2Ev
|
||||
// NO_DTOR_CHECK-NOT: call void @sanitizer_dtor_callback
|
||||
// NO_DTOR_CHECK: ret void
|
Loading…
Reference in New Issue