diff options
author | Vedant Kumar <vsk@apple.com> | 2017-11-09 02:33:38 +0000 |
---|---|---|
committer | Vedant Kumar <vsk@apple.com> | 2017-11-09 02:33:38 +0000 |
commit | 2e8c87590546477736d6744edf8f5cf48bf1ef41 (patch) | |
tree | db6af1baad05772a59d39d29676d98a8ee272dc5 /clang/lib/CodeGen/CoverageMappingGen.cpp | |
parent | c6721f580df11bb0bd00217a45430d163770a278 (diff) | |
download | bcm5719-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.cpp | 27 |
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()); |