[clang] ce7d3e1 - Reland (again) D80966 [codeview] Put !heapallocsite on calls to operator new
Arthur Eubanks via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 9 09:27:55 PDT 2020
Author: Arthur Eubanks
Date: 2020-06-09T09:27:32-07:00
New Revision: ce7d3e1c5531fce828722379cfbd58cb5d4dfab9
URL: https://github.com/llvm/llvm-project/commit/ce7d3e1c5531fce828722379cfbd58cb5d4dfab9
DIFF: https://github.com/llvm/llvm-project/commit/ce7d3e1c5531fce828722379cfbd58cb5d4dfab9.diff
LOG: Reland (again) D80966 [codeview] Put !heapallocsite on calls to operator new
Check that getDebugInfo() is not null, as in the first revision, before
calling getDebugInfo()->addHeapAllocSiteMetadata().
Else would cause a crash with a new expression in a default arg.
---
Clang marks calls to operator new as heap allocation sites, but the
operator declared at global scope returns a void pointer. There is no
explicit cast in the code, so the compiler has to write down the
allocated type itself.
Also generalize a cast to use CallBase, so that we mark heap alloc sites
when exceptions are enabled.
Differential Revision: https://reviews.llvm.org/D80966
Added:
clang/test/CodeGenCXX/debug-info-codeview-heapallocsite.cpp
Modified:
clang/lib/CodeGen/CGCall.cpp
clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/CodeGen/CGDebugInfo.h
clang/lib/CodeGen/CGExprCXX.cpp
clang/lib/CodeGen/CGExprScalar.cpp
clang/test/CodeGen/debug-info-codeview-heapallocsite.c
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 6bde3124555b..136782fccf40 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<MSAllocatorAttr>())
- 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 cc50ec6a8c89..1737154d179a 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 367047e79dc9..96ef6c7c1d27 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 d0012337cdd3..d018443858bd 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -1638,6 +1638,13 @@ 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 &&
+ getDebugInfo())
+ if (auto *newCall = dyn_cast<llvm::CallBase>(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 6a13ca08b8f3..b2bc38b329ef 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<llvm::CallInst>(Src))
- if (CI->getMetadata("heapallocsite") && isa<ExplicitCastExpr>(CE))
- CGF.getDebugInfo()->
- addHeapAllocSiteMetadata(CI, CE->getType(), CE->getExprLoc());
+ // Update heapallocsite metadata when there is an explicit pointer cast.
+ if (auto *CI = dyn_cast<llvm::CallBase>(Src)) {
+ if (CI->getMetadata("heapallocsite") && isa<ExplicitCastExpr>(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 dfc0d19b25e8..25c102b1c37d 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 000000000000..33e60380c698
--- /dev/null
+++ b/clang/test/CodeGenCXX/debug-info-codeview-heapallocsite.cpp
@@ -0,0 +1,38 @@
+// 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 at YAPEAX_K@Z"(i64 4) {{.*}} !heapallocsite [[DBG_FOO:!.*]]
+// CHECK: call {{.*}} i8* {{.*}}@"??2 at 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 at 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"
+
+// a new expression in a default arg has caused crashes in the past, add here to test that edge case
+void foo(int *a = new int) {}
+void bar() { foo(); }
More information about the cfe-commits
mailing list