[Coverage] Adjust skipped regions only if {Prev,Next}TokLoc is in the same file as regions' {start, end}Loc

Fix a bug if {Prev, Next}TokLoc is in different file from skipped regions' {start, end}Loc

Differential Revision: https://reviews.llvm.org/D86116
This commit is contained in:
Zequan Wu 2020-08-17 15:25:08 -07:00
parent 08748d15b8
commit 84fffa6728
3 changed files with 33 additions and 10 deletions

View File

@ -44,7 +44,8 @@ CoverageMappingModuleGen::setUpCoverageCallbacks(Preprocessor &PP) {
PP.setTokenWatcher([CoverageInfo](clang::Token Tok) { PP.setTokenWatcher([CoverageInfo](clang::Token Tok) {
// Update previous token location. // Update previous token location.
CoverageInfo->PrevTokLoc = Tok.getLocation(); CoverageInfo->PrevTokLoc = Tok.getLocation();
CoverageInfo->updateNextTokLoc(Tok.getLocation()); if (Tok.getKind() != clang::tok::eod)
CoverageInfo->updateNextTokLoc(Tok.getLocation());
}); });
return CoverageInfo; return CoverageInfo;
} }
@ -305,20 +306,24 @@ public:
/// non-comment token. If shrinking the skipped range would make it empty, /// non-comment token. If shrinking the skipped range would make it empty,
/// this returns None. /// this returns None.
Optional<SpellingRegion> adjustSkippedRange(SourceManager &SM, Optional<SpellingRegion> adjustSkippedRange(SourceManager &SM,
SpellingRegion SR, SourceLocation LocStart,
SourceLocation LocEnd,
SourceLocation PrevTokLoc, SourceLocation PrevTokLoc,
SourceLocation NextTokLoc) { SourceLocation NextTokLoc) {
SpellingRegion SR{SM, LocStart, LocEnd};
// If Range begin location is invalid, it's not a comment region. // If Range begin location is invalid, it's not a comment region.
if (PrevTokLoc.isInvalid()) if (PrevTokLoc.isInvalid())
return SR; return SR;
unsigned PrevTokLine = SM.getSpellingLineNumber(PrevTokLoc); unsigned PrevTokLine = SM.getSpellingLineNumber(PrevTokLoc);
unsigned NextTokLine = SM.getSpellingLineNumber(NextTokLoc); unsigned NextTokLine = SM.getSpellingLineNumber(NextTokLoc);
SpellingRegion newSR(SR); SpellingRegion newSR(SR);
if (SR.LineStart == PrevTokLine) { if (SM.isWrittenInSameFile(LocStart, PrevTokLoc) &&
SR.LineStart == PrevTokLine) {
newSR.LineStart = SR.LineStart + 1; newSR.LineStart = SR.LineStart + 1;
newSR.ColumnStart = 1; newSR.ColumnStart = 1;
} }
if (SR.LineEnd == NextTokLine) { if (SM.isWrittenInSameFile(LocEnd, NextTokLoc) &&
SR.LineEnd == NextTokLine) {
newSR.LineEnd = SR.LineEnd - 1; newSR.LineEnd = SR.LineEnd - 1;
newSR.ColumnEnd = SR.ColumnStart + 1; newSR.ColumnEnd = SR.ColumnStart + 1;
} }
@ -354,14 +359,13 @@ public:
auto CovFileID = getCoverageFileID(LocStart); auto CovFileID = getCoverageFileID(LocStart);
if (!CovFileID) if (!CovFileID)
continue; continue;
SpellingRegion SR{SM, LocStart, LocEnd}; Optional<SpellingRegion> SR =
if (Optional<SpellingRegion> res = adjustSkippedRange(SM, LocStart, LocEnd, I.PrevTokLoc, I.NextTokLoc);
adjustSkippedRange(SM, SR, I.PrevTokLoc, I.NextTokLoc)) if (!SR.hasValue())
SR = res.getValue();
else
continue; continue;
auto Region = CounterMappingRegion::makeSkipped( auto Region = CounterMappingRegion::makeSkipped(
*CovFileID, SR.LineStart, SR.ColumnStart, SR.LineEnd, SR.ColumnEnd); *CovFileID, SR->LineStart, SR->ColumnStart, SR->LineEnd,
SR->ColumnEnd);
// Make sure that we only collect the regions that are inside // Make sure that we only collect the regions that are inside
// the source code of this function. // the source code of this function.
if (Region.LineStart >= FileLineRanges[*CovFileID].first && if (Region.LineStart >= FileLineRanges[*CovFileID].first &&

View File

@ -0,0 +1,6 @@
x = 0;

View File

@ -0,0 +1,13 @@
// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only %s | FileCheck %s
int f() {
int x = 0;
#include "Inputs/comment.h" /*
*/
return x;
}
// CHECK: File 0, 3:9 -> 8:2 = #0
// CHECK-NEXT: Expansion,File 0, 5:10 -> 5:28 = #0
// CHECK-NEXT: Skipped,File 0, 6:1 -> 6:7 = 0
// CHECK-NEXT: File 1, 1:1 -> 7:1 = #0