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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits