forked from OSchip/llvm-project
Debug Info: Fine-tune the simple return expression location handling to
only affect functions without a separate return block. This fixes the linetable for void functions with cleanups and multiple returns. llvm-svn: 187090
This commit is contained in:
parent
12bdde57a9
commit
524ba1f11d
|
@ -191,14 +191,20 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
|
|||
"mismatched push/pop in break/continue stack!");
|
||||
|
||||
bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0
|
||||
&& NumSimpleReturnExprs == NumReturnExprs;
|
||||
// If the function contains only a simple return statement, the
|
||||
// location before the cleanup code becomes the last useful
|
||||
// breakpoint in the function, because the simple return expression
|
||||
// will be evaluated after the cleanup code. To be safe, set the
|
||||
// debug location for cleanup code to the location of the return
|
||||
// statement. Otherwise the cleanup code should be at the end of the
|
||||
// function's lexical scope.
|
||||
&& NumSimpleReturnExprs == NumReturnExprs
|
||||
&& ReturnBlock.getBlock()->use_empty();
|
||||
// Usually the return expression is evaluated before the cleanup
|
||||
// code. If the function contains only a simple return statement,
|
||||
// such as a constant, the location before the cleanup code becomes
|
||||
// the last useful breakpoint in the function, because the simple
|
||||
// return expression will be evaluated after the cleanup code. To be
|
||||
// safe, set the debug location for cleanup code to the location of
|
||||
// the return statement. Otherwise the cleanup code should be at the
|
||||
// end of the function's lexical scope.
|
||||
//
|
||||
// If there are multiple branches to the return block, the branch
|
||||
// instructions will get the location of the return statements and
|
||||
// all will be fine.
|
||||
if (CGDebugInfo *DI = getDebugInfo()) {
|
||||
if (OnlySimpleReturnStmts)
|
||||
DI->EmitLocation(Builder, LastStopPoint);
|
||||
|
|
|
@ -7,6 +7,12 @@
|
|||
// CHECK: call void @_ZN1CD1Ev(%class.C* {{.*}}), !dbg ![[CLEANUP:[0-9]+]]
|
||||
// CHECK: ret i32 0, !dbg ![[RET:[0-9]+]]
|
||||
|
||||
// CHECK: define {{.*}}bar
|
||||
// CHECK: ret void, !dbg ![[RETBAR:[0-9]+]]
|
||||
|
||||
// CHECK: define {{.*}}baz
|
||||
// CHECK: ret void, !dbg ![[RETBAZ:[0-9]+]]
|
||||
|
||||
class C {
|
||||
public:
|
||||
~C() {}
|
||||
|
@ -22,3 +28,31 @@ int foo()
|
|||
return 0;
|
||||
// CHECK: ![[RET]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
|
||||
}
|
||||
|
||||
void bar()
|
||||
{
|
||||
if (!foo())
|
||||
// CHECK: {{.*}} = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
|
||||
return;
|
||||
|
||||
if (foo()) {
|
||||
C c;
|
||||
c.i = foo();
|
||||
}
|
||||
// Clang creates only a single ret instruction. Make sure it is at a useful line.
|
||||
// CHECK: ![[RETBAR]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
|
||||
}
|
||||
|
||||
void baz()
|
||||
{
|
||||
if (!foo())
|
||||
// CHECK: {{.*}} = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
|
||||
return;
|
||||
|
||||
if (foo()) {
|
||||
// no cleanup
|
||||
// CHECK: {{.*}} = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
|
||||
return;
|
||||
}
|
||||
// CHECK: ![[RETBAZ]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue