From: David Blaikie Date: Wed, 4 Feb 2015 19:47:54 +0000 (+0000) Subject: DebugInfo: Attribute cleanup code to the end of the scope, not the end of the function. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c2d8f6b982132ebf20345f85c415a49b843b67d8;p=clang DebugInfo: Attribute cleanup code to the end of the scope, not the end of the function. 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 --- diff --git a/lib/CodeGen/CGCleanup.cpp b/lib/CodeGen/CGCleanup.cpp index bda8d8e942..566befc915 100644 --- a/lib/CodeGen/CGCleanup.cpp +++ b/lib/CodeGen/CGCleanup.cpp @@ -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); diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 5624ce2f87..c5f358f7a1 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -55,7 +55,6 @@ CGDebugInfo::~CGDebugInfo() { ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF, SourceLocation TemporaryLocation) : CGF(CGF) { - assert(!TemporaryLocation.isInvalid() && "invalid location"); init(TemporaryLocation); } diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index e152bfd749..43c9dfe87a 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -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). diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 03d2ab313f..60e81db375 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -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 diff --git a/test/CodeGenCXX/debug-info-line.cpp b/test/CodeGenCXX/debug-info-line.cpp index 5f32f3ff07..c8d85e6836 100644 --- a/test/CodeGenCXX/debug-info-line.cpp +++ b/test/CodeGenCXX/debug-info-line.cpp @@ -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, diff --git a/test/CodeGenCXX/linetable-cleanup.cpp b/test/CodeGenCXX/linetable-cleanup.cpp index 3a6aa88d94..0e64be19c8 100644 --- a/test/CodeGenCXX/linetable-cleanup.cpp +++ b/test/CodeGenCXX/linetable-cleanup.cpp @@ -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: !{{.*}}) } diff --git a/test/CodeGenObjC/arc-linetable.m b/test/CodeGenObjC/arc-linetable.m index 656c343468..cd746d18c1 100644 --- a/test/CodeGenObjC/arc-linetable.m +++ b/test/CodeGenObjC/arc-linetable.m @@ -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: !{{.*}}) }