summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CoverageMappingGen.cpp
diff options
context:
space:
mode:
authorVedant Kumar <vsk@apple.com>2017-11-09 02:33:38 +0000
committerVedant Kumar <vsk@apple.com>2017-11-09 02:33:38 +0000
commit2e8c87590546477736d6744edf8f5cf48bf1ef41 (patch)
treedb6af1baad05772a59d39d29676d98a8ee272dc5 /clang/lib/CodeGen/CoverageMappingGen.cpp
parentc6721f580df11bb0bd00217a45430d163770a278 (diff)
downloadbcm5719-llvm-2e8c87590546477736d6744edf8f5cf48bf1ef41.tar.gz
bcm5719-llvm-2e8c87590546477736d6744edf8f5cf48bf1ef41.zip
[Coverage] Emit a gap area after if conditions
The area immediately after the closing right-paren of an if condition should have a count equal to the 'then' block's count. Use a gap region to set this count, so that region highlighting for the 'then' block remains precise. This solves a problem we have with wrapped segments. Consider: 1| if (false) 2| foo(); Without a gap area starting after the condition, the wrapped segment from line 1 would make it look like line 2 is executed, when it's not. rdar://35373009 llvm-svn: 317758
Diffstat (limited to 'clang/lib/CodeGen/CoverageMappingGen.cpp')
-rw-r--r--clang/lib/CodeGen/CoverageMappingGen.cpp27
1 files changed, 26 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp
index 08b8c2ec544..2b6e6deb554 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -718,6 +718,19 @@ struct CounterCoverageMappingBuilder
getRegion().setDeferred(true);
}
+ /// Emit a gap region between \p StartLoc and \p EndLoc with the given count.
+ void fillGapAreaWithCount(SourceLocation StartLoc, SourceLocation EndLoc,
+ Counter Count) {
+ if (StartLoc == EndLoc || StartLoc.isMacroID() || EndLoc.isMacroID() ||
+ !SM.isWrittenInSameFile(StartLoc, EndLoc))
+ return;
+ handleFileExit(StartLoc);
+ size_t Index = pushRegion(Count, StartLoc, EndLoc);
+ getRegion().setGap(true);
+ handleFileExit(EndLoc);
+ popRegions(Index);
+ }
+
/// \brief Keep counts of breaks and continues inside loops.
struct BreakContinue {
Counter BreakCount;
@@ -1048,12 +1061,19 @@ struct CounterCoverageMappingBuilder
// counter for the body when looking at the coverage.
propagateCounts(ParentCount, S->getCond());
+ // The 'then' count applies to the area immediately after the condition.
+ fillGapAreaWithCount(getPreciseTokenLocEnd(getEnd(S->getCond())),
+ getStart(S->getThen()), ThenCount);
+
extendRegion(S->getThen());
Counter OutCount = propagateCounts(ThenCount, S->getThen());
Counter ElseCount = subtractCounters(ParentCount, ThenCount);
if (const Stmt *Else = S->getElse()) {
- extendRegion(S->getElse());
+ // The 'else' count applies to the area immediately after the 'then'.
+ fillGapAreaWithCount(getPreciseTokenLocEnd(getEnd(S->getThen())),
+ getStart(Else), ElseCount);
+ extendRegion(Else);
OutCount = addCounters(OutCount, propagateCounts(ElseCount, Else));
} else
OutCount = addCounters(OutCount, ElseCount);
@@ -1090,9 +1110,14 @@ struct CounterCoverageMappingBuilder
Visit(E->getCond());
if (!isa<BinaryConditionalOperator>(E)) {
+ // The 'then' count applies to the area immediately after the condition.
+ fillGapAreaWithCount(E->getQuestionLoc(), getStart(E->getTrueExpr()),
+ TrueCount);
+
extendRegion(E->getTrueExpr());
propagateCounts(TrueCount, E->getTrueExpr());
}
+
extendRegion(E->getFalseExpr());
propagateCounts(subtractCounters(ParentCount, TrueCount),
E->getFalseExpr());
OpenPOWER on IntegriCloud