From f40d28f40288275415367023e0bf9f8c82c2916f Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Thu, 19 Nov 2015 17:41:41 -0800 Subject: [PATCH] Debug Info: Don't reset the debug scope after leaving the outermost scope, because the debugger is not expecting the function epilogue to be in a different scope. rdar://problem/23621232 --- lib/IRGen/IRGenSIL.cpp | 6 ++++-- lib/SILGen/SILGenFunction.h | 6 +++--- test/DebugInfo/return.swift | 13 ++++++++----- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index 12db2a8d8ba00..abb358fdc884d 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -1568,6 +1568,7 @@ void IRGenSILFunction::visitSILBasicBlock(SILBasicBlock *BB) { if (IGM.DebugInfo) { // Set the debug info location for I, if applicable. SILLocation ILoc = I.getLoc(); + auto DS = I.getDebugScope(); // Handle cleanup locations. if (ILoc.getKind() == SILLocation::CleanupKind) { // Cleanup locations point to the decl of the the value that @@ -1591,13 +1592,13 @@ void IRGenSILFunction::visitSILBasicBlock(SILBasicBlock *BB) { if (!KeepCurrentLocation) { assert(BB->getTerminator()); ILoc = BB->getTerminator()->getLoc(); + DS = BB->getTerminator()->getDebugScope(); } } else if (InCleanupBlock) { KeepCurrentLocation = false; InCleanupBlock = false; } - auto DS = I.getDebugScope(); assert((!DS || (DS->SILFn == CurSILFn || DS->InlinedCallSite)) && "insn was not inlined, but belongs to a different function"); @@ -1612,7 +1613,8 @@ void IRGenSILFunction::visitSILBasicBlock(SILBasicBlock *BB) { // Ignore scope-less instructions and have IRBuilder reuse the // previous location and scope. - if (DS && !KeepCurrentLocation) + if (DS && !KeepCurrentLocation && + !(ILoc.isInPrologue() && ILoc.getKind() == SILLocation::CleanupKind)) IGM.DebugInfo->setCurrentLoc(Builder, DS, ILoc); // Function argument handling. diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h index aa3e3eedd0541..fcf3b222c2c3a 100644 --- a/lib/SILGen/SILGenFunction.h +++ b/lib/SILGen/SILGenFunction.h @@ -502,9 +502,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction DebugScopeStack.pop_back(); if (DebugScopeStack.size()) B.setCurrentDebugScope(DebugScopeStack.back()); - else { - B.setCurrentDebugScope(F.getDebugScope()); - } + // Don't reset the debug scope after leaving the outermost scope, + // because the debugger is not expecting the function epilogue to + // be in a different scope. } //===--------------------------------------------------------------------===// diff --git a/test/DebugInfo/return.swift b/test/DebugInfo/return.swift index 65107b9c1963c..d59aecbeb6bf7 100644 --- a/test/DebugInfo/return.swift +++ b/test/DebugInfo/return.swift @@ -9,7 +9,8 @@ class X { public func ifelseexpr() -> Int64 { var x = X(i:0); // CHECK: [[META:%.*]] = call %swift.type* @_TMaC6return1X() - // CHECK: [[X:%.*]] = call %C6return1X* @_TFC6return1XCfT1iVs5Int64_S0_(i64 0, %swift.type* [[META]]) + // CHECK: [[X:%.*]] = call %C6return1X* @_TFC6return1XCfT1iVs5Int64_S0_( + // CHECK-SAME: i64 0, %swift.type* [[META]]) // CHECK: @swift_release to void (%C6return1X*)*)(%C6return1X* [[X]]) if true { x.x++; @@ -17,9 +18,11 @@ public func ifelseexpr() -> Int64 { x.x--; } // CHECK: @swift_release to void (%C6return1X*)*)(%C6return1X* [[X]]) - // CHECK: @swift_release to void (%C6return1X*)*)(%C6return1X* [[X]]) {{.*}}, !dbg ![[RELEASE:.*]] - // CHECK: ret{{.*}}, !dbg ![[RET:.*]] - // CHECK: ![[RELEASE]] = !DILocation(line: [[@LINE+1]], - return x.x; // CHECK: ![[RET]] = !DILocation(line: [[@LINE]], + // CHECK: @swift_release to void (%C6return1X*)*)(%C6return1X* [[X]]) + // CHECK-SAME: , !dbg ![[RELEASE:.*]] + + // The ret instruction should be in the same scope as the return expression. + // CHECK: ret{{.*}}, !dbg ![[RELEASE]] + return x.x; // CHECK: ![[RELEASE]] = !DILocation(line: [[@LINE]], column: 3 }