diff options
-rw-r--r-- | clang/lib/CodeGen/CoverageMappingGen.cpp | 30 | ||||
-rw-r--r-- | clang/test/CoverageMapping/deferred-region.cpp | 22 |
2 files changed, 44 insertions, 8 deletions
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 15c81945e0b..08b8c2ec544 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -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) { diff --git a/clang/test/CoverageMapping/deferred-region.cpp b/clang/test/CoverageMapping/deferred-region.cpp index 743b635a907..3504588a6c3 100644 --- a/clang/test/CoverageMapping/deferred-region.cpp +++ b/clang/test/CoverageMapping/deferred-region.cpp @@ -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); |