Skip to content
Snippets Groups Projects
Commit fe8249cb authored by Vedant Kumar's avatar Vedant Kumar
Browse files

[Coverage] Discard deferred region in closing if-else

A trailing deferred region isn't necessary in a function that ends with
this pattern:

  ...
  else {
    ...
    return;
  }

Special-case this pattern so that the closing curly brace of the
function isn't marked as uncovered. This issue came up in PR34962.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@315982 91177308-0d34-0410-b5e6-96231b3b80d8
parent 762d1e77
No related branches found
No related tags found
No related merge requests found
......@@ -758,6 +758,22 @@ struct CounterCoverageMappingBuilder
handleFileExit(getEnd(S));
}
/// Determine whether the final deferred region emitted in \p Body should be
/// discarded.
static bool discardFinalDeferredRegionInDecl(Stmt *Body) {
if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
Stmt *LastStmt = CS->body_back();
if (auto *IfElse = dyn_cast<IfStmt>(LastStmt)) {
if (auto *Else = dyn_cast_or_null<CompoundStmt>(IfElse->getElse()))
LastStmt = Else->body_back();
else
LastStmt = IfElse->getElse();
}
return dyn_cast_or_null<ReturnStmt>(LastStmt);
}
return false;
}
void VisitDecl(const Decl *D) {
assert(!DeferredRegion && "Deferred region never completed");
......@@ -770,14 +786,14 @@ struct CounterCoverageMappingBuilder
Counter ExitCount = propagateCounts(getRegionCounter(Body), Body);
assert(RegionStack.empty() && "Regions entered but never exited");
// Special case: if the last statement is a return, throw away the
// deferred region. This allows the closing brace to have a count.
if (auto *CS = dyn_cast_or_null<CompoundStmt>(Body))
if (dyn_cast_or_null<ReturnStmt>(CS->body_back()))
if (DeferredRegion) {
// Complete (or discard) any deferred regions introduced by the last
// statement.
if (discardFinalDeferredRegionInDecl(Body))
DeferredRegion = None;
// Complete any deferred regions introduced by the last statement.
popRegions(completeDeferred(ExitCount, getEnd(Body)));
else
popRegions(completeDeferred(ExitCount, getEnd(Body)));
}
}
void VisitReturnStmt(const ReturnStmt *S) {
......
......@@ -31,11 +31,28 @@ void baz() { // CHECK: [[@LINE]]:12 -> [[@LINE+2]]:2
// CHECK-LABEL: _Z3mazv:
void maz() {
if (true)
return; // CHECK: Gap,File 0, [[@LINE]]:11 -> 36:3 = (#0 - #1)
return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
return; // CHECK-NOT: Gap
}
// CHECK-LABEL: _Z4maazv:
void maaz() {
if (true)
return; // CHECK: Gap,File 0, [[@LINE]]:11
else
return; // CHECK-NOT: Gap,File 0, [[@LINE]]
}
// CHECK-LABEL: _Z5maaazv:
void maaaz() {
if (true) {
return;
} else { // CHECK: Gap,File 0, [[@LINE]]:4 -> [[@LINE]]:10
return; // CHECK-NOT: Gap,File 0, [[@LINE]]
}
}
// CHECK-LABEL: _Z3bari:
void bar(int x) {
IF (x)
......@@ -158,6 +175,9 @@ int main() {
foo(1);
fooo(0);
fooo(1);
maz();
maaz();
maaaz();
baz();
bar(0);
bar(1);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment