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/CodeGen/sanitize-dtor-usage.cpp =================================================================== --- /dev/null +++ test/CodeGen/sanitize-dtor-usage.cpp @@ -0,0 +1,22 @@ +// Test -fsanitize-memory-use-after-dtor +// RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -emit-llvm -o - %s | FileCheck %s --check-prefix=DTOR + +//#include +struct A { + int x_; + A() { + x_ = 5; + } + ~A() { + // __msan_poison(this, sizeof(*this)); + } +}; +int main() { + A a; + a.~A(); + //__msan_check_mem_is_initialized(&a.x_, sizeof(a.x_)); +} + +// Check that MSan destructor sanitization poisons simple internal attribute +// DTOR: call void @__sanitizer_dtor_callback +// CHECK: ret void