summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2015-01-14 07:10:46 +0000
committerDavid Blaikie <dblaikie@gmail.com>2015-01-14 07:10:46 +0000
commit57732cd49af48a1c43e98e62fa0890b1cd639fd2 (patch)
tree431e7b6649cb712582981652358444b863cd55e3
parent21f4ef7237c48b88f311ae294c554769c327e015 (diff)
DebugInof: Correct the location of exception cleanups in global ctors/dtors and ObjC methods
Without setting the CurEHLocation these cleanups would be attributed to whatever the last active debug line location was (the 'fn' call in the included test cases). By setting CurEHLocation correctly the line information is improved/corrected. This quality bug turned into a crasher with r225000 when, instead of allowing the last location to persist, it would be zero'd out. This could lead to a function call (such as the dtor) being made without a debug location - if that call was subsequently inlined (and the caller and callee had debug info, just not the call instruction) the inliner would violate important constraints about the debug location chains by not updating the inlined instructions to chain up to the callee locations. So, by fixing this bug, I am addressing the assertion failures introduced by r225000 and should be able to recommit that patch with impunity... git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@225955 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGDeclCXX.cpp4
-rw-r--r--lib/CodeGen/CGObjC.cpp1
-rw-r--r--test/CodeGenCXX/debug-info-line.cpp27
-rw-r--r--test/CodeGenObjCXX/debug-info-line.mm20
4 files changed, 48 insertions, 4 deletions
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp
index 12cdb95097..9bfad21718 100644
--- a/lib/CodeGen/CGDeclCXX.cpp
+++ b/lib/CodeGen/CGDeclCXX.cpp
@@ -445,6 +445,8 @@ void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
if (D->hasAttr<NoDebugAttr>())
DebugInfo = nullptr; // disable debug info indefinitely for this function
+ CurEHLocation = D->getLocStart();
+
StartFunction(GlobalDecl(D), getContext().VoidTy, Fn,
getTypes().arrangeNullaryFunction(),
FunctionArgList(), D->getLocation(),
@@ -554,6 +556,8 @@ llvm::Function *CodeGenFunction::generateDestroyHelper(
llvm::Function *fn = CGM.CreateGlobalInitOrDestructFunction(
FTy, "__cxx_global_array_dtor", VD->getLocation());
+ CurEHLocation = VD->getLocStart();
+
StartFunction(VD, getContext().VoidTy, fn, FI, args);
emitDestroy(addr, type, destroyer, useEHCleanupForArray);
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index d56d3e36d4..34c6d94f88 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -476,6 +476,7 @@ void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
args.push_back(PI);
CurGD = OMD;
+ CurEHLocation = OMD->getLocEnd();
StartFunction(OMD, OMD->getReturnType(), Fn, FI, args,
OMD->getLocation(), StartLoc);
diff --git a/test/CodeGenCXX/debug-info-line.cpp b/test/CodeGenCXX/debug-info-line.cpp
index ba3b870078..7a6d6543a9 100644
--- a/test/CodeGenCXX/debug-info-line.cpp
+++ b/test/CodeGenCXX/debug-info-line.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -g -std=c++11 -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -g -std=c++11 -S -emit-llvm %s -o - | FileCheck %s
int &src();
int *sink();
@@ -110,6 +110,29 @@ void f10() {
new (void_src()) int(src()));
}
+// noexcept just to simplify the codegen a bit
+void fn() noexcept(true);
+
+struct bar {
+ bar();
+ // noexcept(false) to convolute the global dtor
+ ~bar() noexcept(false);
+};
+// global ctor cleanup
+// CHECK-LABEL: define
+// CHECK: invoke{{ }}
+// CHECK: invoke{{ }}
+// CHECK: to label {{.*}}, !dbg [[DBG_GLBL_CTOR_B:!.*]]
+// global dtor cleanup
+// CHECK-LABEL: define
+// CHECK: invoke{{ }}
+// CHECK: invoke{{ }}
+// CHECK: to label {{.*}}, !dbg [[DBG_GLBL_DTOR_B:!.*]]
+#line 1500
+bar b[1] = { //
+ (fn(), //
+ bar())};
+
// CHECK: [[DBG_F1]] = !{i32 100,
// CHECK: [[DBG_FOO_VALUE]] = !{i32 200,
// CHECK: [[DBG_FOO_REF]] = !{i32 202,
@@ -124,3 +147,5 @@ void f10() {
// CHECK: [[DBG_F9]] = !{i32 1000,
// CHECK: [[DBG_F10_ICMP]] = !{i32 1100,
// CHECK: [[DBG_F10_STORE]] = !{i32 1100,
+// CHECK: [[DBG_GLBL_CTOR_B]] = !{i32 1500,
+// CHECK: [[DBG_GLBL_DTOR_B]] = !{i32 1500,
diff --git a/test/CodeGenObjCXX/debug-info-line.mm b/test/CodeGenObjCXX/debug-info-line.mm
index f38ab5f28a..f3546a12a6 100644
--- a/test/CodeGenObjCXX/debug-info-line.mm
+++ b/test/CodeGenObjCXX/debug-info-line.mm
@@ -6,11 +6,25 @@ struct foo {
~foo();
};
-void func() {
+void f1() {
^{
foo f;
fn();
- // CHECK: cleanup, !dbg [[LINE:![0-9]*]]
- // CHECK: [[LINE]] = !{i32 [[@LINE+1]],
+ // CHECK: cleanup, !dbg [[DBG_F1:![0-9]*]]
+#line 100
}();
}
+
+// CHECK-LABEL: define internal i8* @"\01-[TNSObject init]"
+@implementation TNSObject
+- (id)init
+{
+ foo f;
+ fn();
+ // CHECK: cleanup, !dbg [[DBG_TNSO:![0-9]*]]
+#line 200
+}
+@end
+
+// CHECK: [[DBG_F1]] = !{i32 100,
+// CHECK: [[DBG_TNSO]] = !{i32 200,