Index: lib/CodeGen/CGClass.cpp =================================================================== --- lib/CodeGen/CGClass.cpp +++ lib/CodeGen/CGClass.cpp @@ -1448,6 +1448,29 @@ // Exit the try if applicable. if (isTryBody) ExitCXXTryStmt(*cast(Body), true); + + // Insert memory-posioning instrumentation. + // Generates function call for handling object poisoning, passing in + // references to 'this' and its size as arguments. + if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor) { + const ASTRecordLayout &Layout = + getContext().getASTRecordLayout(Dtor->getParent()); + + llvm::Value *Args[2] = { + Builder.CreateBitCast(LoadCXXThis(), VoidPtrTy), + llvm::ConstantInt::get(CGM.SizeTy, Layout.getSize().getQuantity()) + }; + llvm::Type *ArgTypes[2] = { + VoidPtrTy, + SizeTy + }; + + llvm::FunctionType *FnType = + llvm::FunctionType::get(CGM.VoidTy, ArgTypes, false); + llvm::Value *Fn = + CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback"); + EmitNounwindRuntimeCall(Fn, Args); + } } void CodeGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &Args) { Index: test/CodeGenCXX/sanitize-dtor-callback.cpp =================================================================== --- /dev/null +++ test/CodeGenCXX/sanitize-dtor-callback.cpp @@ -0,0 +1,20 @@ +// 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 { + int x; + ~Simple() {} +}; + +int main() { + Simple s; + s.~Simple(); +} +// Simple internal member is poisoned by compiler-generated dtor +// CHECK-LABEL: define linkonce_odr void @_ZN6SimpleD2Ev +// CHECK: call void @__sanitizer_dtor_callback +// CHECK: ret void + +// NO_DTOR_CHECK-NOT: call void @sanitizer_dtor_callback +// NO_DTOR_CHECK: ret void