diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 6bde3124555b42..136782fccf4099 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -4951,7 +4951,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, // Add metadata for calls to MSAllocator functions if (getDebugInfo() && TargetDecl && TargetDecl->hasAttr()) - getDebugInfo()->addHeapAllocSiteMetadata(CI, RetTy, Loc); + getDebugInfo()->addHeapAllocSiteMetadata(CI, RetTy->getPointeeType(), Loc); // 4. Finish the call. diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index cc50ec6a8c897f..1737154d179a68 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2146,16 +2146,14 @@ llvm::DIType *CGDebugInfo::getOrCreateStandaloneType(QualType D, return T; } -void CGDebugInfo::addHeapAllocSiteMetadata(llvm::Instruction *CI, - QualType D, +void CGDebugInfo::addHeapAllocSiteMetadata(llvm::CallBase *CI, + QualType AllocatedTy, SourceLocation Loc) { llvm::MDNode *node; - if (D.getTypePtr()->isVoidPointerType()) { + if (AllocatedTy->isVoidType()) node = llvm::MDNode::get(CGM.getLLVMContext(), None); - } else { - QualType PointeeTy = D.getTypePtr()->getPointeeType(); - node = getOrCreateType(PointeeTy, getOrCreateFile(Loc)); - } + else + node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc)); CI->setMetadata("heapallocsite", node); } diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index 367047e79dc9fc..96ef6c7c1d27d8 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -509,7 +509,7 @@ class CGDebugInfo { llvm::DIType *getOrCreateStandaloneType(QualType Ty, SourceLocation Loc); /// Add heapallocsite metadata for MSAllocator calls. - void addHeapAllocSiteMetadata(llvm::Instruction *CallSite, QualType Ty, + void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc); void completeType(const EnumDecl *ED); diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index d0012337cdd316..23cc97bcdc9f5c 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -1638,6 +1638,12 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { RValue RV = EmitNewDeleteCall(*this, allocator, allocatorType, allocatorArgs); + // Set !heapallocsite metadata on the call to operator new. + if (CGM.getCodeGenOpts().getDebugInfo() != codegenoptions::NoDebugInfo) + if (auto *newCall = dyn_cast(RV.getScalarVal())) + getDebugInfo()->addHeapAllocSiteMetadata(newCall, allocType, + E->getExprLoc()); + // If this was a call to a global replaceable allocation function that does // not take an alignment argument, the allocator is known to produce // storage that's suitably aligned for any object that fits, up to a known diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index cabfe0cca28152..4e61349cf4d512 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -2081,11 +2081,15 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { } } - // Update heapallocsite metadata when there is an explicit cast. - if (llvm::CallInst *CI = dyn_cast(Src)) - if (CI->getMetadata("heapallocsite") && isa(CE)) - CGF.getDebugInfo()-> - addHeapAllocSiteMetadata(CI, CE->getType(), CE->getExprLoc()); + // Update heapallocsite metadata when there is an explicit pointer cast. + if (auto *CI = dyn_cast(Src)) { + if (CI->getMetadata("heapallocsite") && isa(CE)) { + QualType PointeeType = DestTy->getPointeeType(); + if (!PointeeType.isNull()) + CGF.getDebugInfo()->addHeapAllocSiteMetadata(CI, PointeeType, + CE->getExprLoc()); + } + } return Builder.CreateBitCast(Src, DstTy); } diff --git a/clang/test/CodeGen/debug-info-codeview-heapallocsite.c b/clang/test/CodeGen/debug-info-codeview-heapallocsite.c index dfc0d19b25e853..25c102b1c37dd9 100644 --- a/clang/test/CodeGen/debug-info-codeview-heapallocsite.c +++ b/clang/test/CodeGen/debug-info-codeview-heapallocsite.c @@ -1,19 +1,22 @@ -// RUN: %clang_cc1 -triple x86_64-windows-msvc -debug-info-kind=limited -gcodeview -fdeclspec -S -emit-llvm < %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-windows-msvc -debug-info-kind=limited -gcodeview -fdeclspec -S -emit-llvm %s -o - | FileCheck %s struct Foo; struct Bar; __declspec(allocator) void *alloc_void(); +__declspec(allocator) struct Foo *alloc_foo(); void call_alloc() { struct Foo *p = alloc_void(); + struct Foo *w = alloc_foo(); struct Foo *q = (struct Foo*)alloc_void(); struct Foo *r = (struct Foo*)(struct Bar*)alloc_void(); } // CHECK-LABEL: define {{.*}}void @call_alloc // CHECK: call i8* {{.*}}@alloc_void{{.*}} !heapallocsite [[DBG1:!.*]] -// CHECK: call i8* {{.*}}@alloc_void{{.*}} !heapallocsite [[DBG2:!.*]] +// CHECK: call %struct.Foo* {{.*}}@alloc_foo{{.*}} !heapallocsite [[DBG2:!.*]] +// CHECK: call i8* {{.*}}@alloc_void{{.*}} !heapallocsite [[DBG2]] // CHECK: call i8* {{.*}}@alloc_void{{.*}} !heapallocsite [[DBG3:!.*]] // CHECK: [[DBG1]] = !{} diff --git a/clang/test/CodeGenCXX/debug-info-codeview-heapallocsite.cpp b/clang/test/CodeGenCXX/debug-info-codeview-heapallocsite.cpp new file mode 100644 index 00000000000000..ab1101c6709429 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-codeview-heapallocsite.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -fexceptions -triple x86_64-windows-msvc -debug-info-kind=limited -gcodeview -fdeclspec -S -emit-llvm %s -o - | FileCheck %s + +struct Foo { + int x; +}; +struct Bar { + int y; +}; +extern Foo *gv_foo; +extern Bar *gv_bar; +extern "C" void doit() { + gv_foo = new Foo(); + gv_bar = new Bar(); +} + +// CHECK-LABEL: define {{.*}}void @doit +// CHECK: call {{.*}} i8* {{.*}}@"??2@YAPEAX_K@Z"(i64 4) {{.*}} !heapallocsite [[DBG_FOO:!.*]] +// CHECK: call {{.*}} i8* {{.*}}@"??2@YAPEAX_K@Z"(i64 4) {{.*}} !heapallocsite [[DBG_BAR:!.*]] + +extern "C" void useinvoke() { + struct HasDtor { + ~HasDtor() { delete gv_foo; } + } o; + gv_foo = new Foo(); +} + +// CHECK-LABEL: define {{.*}}void @useinvoke +// CHECK: invoke {{.*}} i8* {{.*}}@"??2@YAPEAX_K@Z"(i64 4) +// CHECK-NEXT: to label {{.*}} unwind label {{.*}} !heapallocsite [[DBG_FOO]] + +// CHECK: [[DBG_FOO]] = distinct !DICompositeType(tag: DW_TAG_structure_type, +// CHECK-SAME: name: "Foo" +// CHECK: [[DBG_BAR]] = distinct !DICompositeType(tag: DW_TAG_structure_type, +// CHECK-SAME: name: "Bar"