]> granicus.if.org Git - clang/commitdiff
DebugInof: Correct the location of exception cleanups in global ctors/dtors and ObjC...
authorDavid Blaikie <dblaikie@gmail.com>
Wed, 14 Jan 2015 07:10:46 +0000 (07:10 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Wed, 14 Jan 2015 07:10:46 +0000 (07:10 +0000)
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

lib/CodeGen/CGDeclCXX.cpp
lib/CodeGen/CGObjC.cpp
test/CodeGenCXX/debug-info-line.cpp
test/CodeGenObjCXX/debug-info-line.mm

index 12cdb950978577723807698aec1b0a847db44949..9bfad2171853d87d646ca019be7e55431abb863c 100644 (file)
@@ -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);
index d56d3e36d49150376db019693144ffeb293c46f0..34c6d94f8817c800fc5f62b3a2ae7d697f648152 100644 (file)
@@ -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);
index ba3b8700789185cdcea7f216b34ae370431a9525..7a6d6543a9e5641e57d16b105ebe50d538829234 100644 (file)
@@ -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,
index f38ab5f28abecc1763a0e23254cb124ad069bf3e..f3546a12a6d2d89fe99db80071114021bb7ab355 100644 (file)
@@ -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,