r315982 - [Coverage] Discard deferred region in closing if-else
Vedant Kumar via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 17 00:47:39 PDT 2017
Author: vedantk
Date: Tue Oct 17 00:47:39 2017
New Revision: 315982
URL: http://llvm.org/viewvc/llvm-project?rev=315982&view=rev
Log:
[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.
Modified:
cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp
cfe/trunk/test/CoverageMapping/deferred-region.cpp
Modified: cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp?rev=315982&r1=315981&r2=315982&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp (original)
+++ cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp Tue Oct 17 00:47:39 2017
@@ -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) {
Modified: cfe/trunk/test/CoverageMapping/deferred-region.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CoverageMapping/deferred-region.cpp?rev=315982&r1=315981&r2=315982&view=diff
==============================================================================
--- cfe/trunk/test/CoverageMapping/deferred-region.cpp (original)
+++ cfe/trunk/test/CoverageMapping/deferred-region.cpp Tue Oct 17 00:47:39 2017
@@ -31,11 +31,28 @@ void baz() { // CHECK: [[@LINE]]:12 -> [
// 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);
More information about the cfe-commits
mailing list