summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2014-06-25 17:57:34 +0000
committerDavid Blaikie <dblaikie@gmail.com>2014-06-25 17:57:34 +0000
commitccaf37e1c9c5e4bf74224ef779d62b3ba05e3615 (patch)
tree0d9cdc49b94bb2b50893736254e709cf50fed6c9
parent525f68c5da062214c9bca4d85b9febf8d8ebef5b (diff)
downloadclang-ccaf37e1c9c5e4bf74224ef779d62b3ba05e3615.tar.gz
clang-ccaf37e1c9c5e4bf74224ef779d62b3ba05e3615.tar.bz2
clang-ccaf37e1c9c5e4bf74224ef779d62b3ba05e3615.tar.xz
PR20038: DebugInfo: Call sites without DebugLocs for temporary dtors after a conditional
With && at the top level of an expression, the last thing done when emitting the expression was an unconditional jump to the cleanup block. To reduce the amount of stepping, the DebugLoc is omitted from the unconditional jump. This is done by clearing the IRBuilder's "CurrentDebugLocation"*. If this is not set to some non-empty value before the cleanup block is emitted, the cleanups don't get a location either. If a call without a location is emitted in a function with debug info, and that call is then inlined - bad things happen. (without a location for the call site, the inliner would just leave the inlined DebugLocs as they were - pointing to roots in the original function, not inlined into the current function) Follow up commit to LLVM will ensure that breaking the invariants of the DebugLoc chains by having chains that don't lead to the current function will fail assertions, so we shouldn't accidentally slip any of these cases in anymore. Those assertions may reveal further cases that need to be fixed in clang, though I've tried to test heavily to avoid that. * See r128471, r128513 for the code that clears the CurrentDebugLocation. Simply removing this code or moving the code into IRBuilder to apply to all unconditional branches would regress desired behavior, unfortunately. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211722 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGExprScalar.cpp5
-rw-r--r--test/CodeGenCXX/PR20038.cpp11
2 files changed, 15 insertions, 1 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 14ef5b7982..046ee33271 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -358,7 +358,10 @@ public:
Value *VisitExprWithCleanups(ExprWithCleanups *E) {
CGF.enterFullExpression(E);
CodeGenFunction::RunCleanupsScope Scope(CGF);
- return Visit(E->getSubExpr());
+ auto *V = Visit(E->getSubExpr());
+ if (CGDebugInfo *DI = CGF.getDebugInfo())
+ DI->EmitLocation(Builder, E->getLocEnd(), false);
+ return V;
}
Value *VisitCXXNewExpr(const CXXNewExpr *E) {
return CGF.EmitCXXNewExpr(E);
diff --git a/test/CodeGenCXX/PR20038.cpp b/test/CodeGenCXX/PR20038.cpp
new file mode 100644
index 0000000000..8b3ffc6f53
--- /dev/null
+++ b/test/CodeGenCXX/PR20038.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -g -emit-llvm %s -o - | FileCheck %s
+
+struct C {
+ ~C();
+};
+extern bool b;
+// CHECK: call void @_ZN1CD1Ev({{.*}}), !dbg [[DTOR_CALL_LOC:![0-9]*]]
+// CHECK: [[FUN4:.*]] = {{.*}}; [ DW_TAG_subprogram ] {{.*}} [def] [fun4]
+// CHECK: [[DTOR_CALL_LOC]] = metadata !{i32 [[@LINE+2]], i32 0, metadata [[FUN4_BLOCK:.*]], null}
+// CHECK: [[FUN4_BLOCK]] = metadata !{{{[^,]*}}, {{[^,]*}}, metadata [[FUN4]],
+void fun4() { b && (C(), 1); }