]> granicus.if.org Git - clang/commitdiff
DebugInfo: Attribute cleanup code to the end of the scope, not the end of the function.
authorDavid Blaikie <dblaikie@gmail.com>
Wed, 4 Feb 2015 19:47:54 +0000 (19:47 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Wed, 4 Feb 2015 19:47:54 +0000 (19:47 +0000)
Now if you break on a dtor and go 'up' in your debugger (or you get an
asan failure in a dtor) during an exception unwind, you'll have more
context. Instead of all dtors appearing to be called from the '}' of the
function, they'll be attributed to the end of the scope of the variable,
the same as the non-exceptional dtor call.

This doesn't /quite/ remove all uses of CurEHLocation (which might be
nice to remove, for a few reasons) - it's still used to choose the
location for some other work in the landing pad. It'd be nice to
attribute that code to the same location as the exception calls within
the block and to remove CurEHLocation.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@228181 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCleanup.cpp
lib/CodeGen/CGDebugInfo.cpp
lib/CodeGen/CodeGenFunction.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGenCXX/debug-info-line.cpp
test/CodeGenCXX/linetable-cleanup.cpp
test/CodeGenObjC/arc-linetable.m

index bda8d8e942c14568df031879545a9b5fdde2309a..566befc915cfec71095b45d0648b01cb7fa02c49 100644 (file)
@@ -861,8 +861,6 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) {
 
   // Emit the EH cleanup if required.
   if (RequiresEHCleanup) {
-    auto AL = ApplyDebugLocation::CreateDefaultArtificial(*this, CurEHLocation);
-
     CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
 
     EmitBlock(EHEntry);
index 5624ce2f871b87c76ea896cbede57692d30e5990..c5f358f7a1b27e1524f226c0d21572eaefa76a52 100644 (file)
@@ -55,7 +55,6 @@ CGDebugInfo::~CGDebugInfo() {
 ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF,
                                        SourceLocation TemporaryLocation)
     : CGF(CGF) {
-  assert(!TemporaryLocation.isInvalid() && "invalid location");
   init(TemporaryLocation);
 }
 
index e152bfd74910af5282f8f698f65295e4bec3d46a..43c9dfe87a09d91606b1ffbafa17bc24ecee8aae 100644 (file)
@@ -241,8 +241,6 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
   // edges will be *really* confused.
   bool EmitRetDbgLoc = true;
   if (EHStack.stable_begin() != PrologueCleanupDepth) {
-    PopCleanupBlocks(PrologueCleanupDepth);
-
     // Make sure the line table doesn't jump back into the body for
     // the ret after it's been at EndLoc.
     EmitRetDbgLoc = false;
@@ -250,6 +248,8 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
     if (CGDebugInfo *DI = getDebugInfo())
       if (OnlySimpleReturnStmts)
         DI->EmitLocation(Builder, EndLoc);
+
+    PopCleanupBlocks(PrologueCleanupDepth);
   }
 
   // Emit function epilog (to return).
index 03d2ab313fb242d654296d7e26db7d111d9c23bd..60e81db3753cb8581d9412e8418a8ae57a9164ba 100644 (file)
@@ -567,7 +567,10 @@ public:
 
       // If we should perform a cleanup, force them now.  Note that
       // this ends the cleanup scope before rescoping any labels.
-      if (PerformCleanup) ForceCleanup();
+      if (PerformCleanup) {
+        ApplyDebugLocation DL(CGF, Range.getEnd());
+        ForceCleanup();
+      }
     }
 
     /// \brief Force the emission of cleanups now, instead of waiting
index 5f32f3ff07f49a370974b701f52b13eaa153e957..c8d85e683620ac4a370e6bab6dd9a485a6899d56 100644 (file)
@@ -259,6 +259,21 @@ void f21() {
   f21_b();
 }
 
+// CHECK-LABEL: define
+struct f22_dtor {
+  ~f22_dtor();
+};
+void f22() {
+  {
+    f22_dtor f;
+    src();
+// CHECK: call {{.*}}src
+// CHECK: call {{.*}}, !dbg [[DBG_F22:![0-9]*]]
+// CHECK: call {{.*}}, !dbg [[DBG_F22]]
+#line 2400
+  }
+}
+
 // CHECK: [[DBG_F1]] = !MDLocation(line: 100,
 // CHECK: [[DBG_FOO_VALUE]] = !MDLocation(line: 200,
 // CHECK: [[DBG_FOO_REF]] = !MDLocation(line: 202,
index 3a6aa88d9464ee002d035e80cee57224072e159d..0e64be19c8435dfed34bb06b707fa11e08eaa224 100644 (file)
@@ -4,8 +4,8 @@
 // simple return expressions.
 
 // CHECK: define {{.*}}foo
-// CHECK: call void @_ZN1CD1Ev(%class.C* {{.*}}), !dbg ![[CLEANUP:[0-9]+]]
-// CHECK: ret i32 0, !dbg ![[RET:[0-9]+]]
+// CHECK: call void @_ZN1CD1Ev(%class.C* {{.*}}), !dbg ![[RET:[0-9]+]]
+// CHECK: ret i32 0, !dbg ![[RET]]
 
 // CHECK: define {{.*}}bar
 // CHECK: ret void, !dbg ![[RETBAR:[0-9]+]]
@@ -23,9 +23,8 @@ int foo()
 {
   C c;
   c.i = 42;
-  // This breakpoint should be at/before the cleanup code.
-  // CHECK: ![[CLEANUP]] = !MDLocation(line: [[@LINE+1]], scope: !{{.*}})
   return 0;
+  // This breakpoint should be at/before the cleanup code.
   // CHECK: ![[RET]] = !MDLocation(line: [[@LINE+1]], scope: !{{.*}})
 }
 
index 656c34346879916d74842109b07a874c295e4e4e..cd746d18c13d088f6a2cedfa0e0d2deb481b1a3a 100644 (file)
@@ -4,8 +4,8 @@
 
 // CHECK: define {{.*}}testNoSideEffect
 // CHECK: call void @objc_storeStrong{{.*}}
-// CHECK: call void @objc_storeStrong{{.*}} !dbg ![[ARC1:[0-9]+]]
-// CHECK: ret {{.*}} !dbg ![[RET1:[0-9]+]]
+// CHECK: call void @objc_storeStrong{{.*}} !dbg ![[RET1:[0-9]+]]
+// CHECK: ret {{.*}} !dbg ![[RET1]]
 
 // CHECK: define {{.*}}testNoCleanup
 // CHECK: ret {{.*}} !dbg ![[RET2:[0-9]+]]
@@ -21,8 +21,8 @@
 
 // CHECK: define {{.*}}testVoid
 // CHECK: call void @objc_storeStrong{{.*}}
-// CHECK: call void @objc_storeStrong{{.*}} !dbg ![[ARC5:[0-9]+]]
-// CHECK: ret {{.*}} !dbg ![[RET5:[0-9]+]]
+// CHECK: call void @objc_storeStrong{{.*}} !dbg ![[RET5:[0-9]+]]
+// CHECK: ret {{.*}} !dbg ![[RET5]]
 
 // CHECK: define {{.*}}testVoidNoReturn
 // CHECK: @objc_msgSend{{.*}} !dbg ![[MSG6:[0-9]+]]
@@ -57,9 +57,8 @@ typedef signed char BOOL;
 // CHECK: ![[TESTNOSIDEEFFECT:.*]] = {{.*}}[ DW_TAG_subprogram ] [line [[@LINE+1]]] [local] [def] [-[AppDelegate testNoSideEffect:]]
 - (int)testNoSideEffect:(NSString *)foo {
   int x = 1;
-  // CHECK: ![[ARC1]] = !MDLocation(line: [[@LINE+1]], scope: ![[TESTNOSIDEEFFECT]])
   return 1; // Return expression
-  // CHECK: ![[RET1]] = !MDLocation(line: [[@LINE+1]], scope: !{{.*}})
+  // CHECK: ![[RET1]] = !MDLocation(line: [[@LINE+1]], scope: ![[TESTNOSIDEEFFECT]])
 }           // Cleanup + Ret
 
 - (int)testNoCleanup {
@@ -82,7 +81,6 @@ typedef signed char BOOL;
 }
 
 - (void)testVoid:(NSString *)foo {
-  // CHECK: ![[ARC5]] = !MDLocation(line: [[@LINE+1]], scope: !{{.*}})
   return;
   // CHECK: ![[RET5]] = !MDLocation(line: [[@LINE+1]], scope: !{{.*}})
 }