|
17 | 17 | #include "clang/Basic/FileManager.h"
|
18 | 18 | #include "clang/Frontend/FrontendDiagnostic.h"
|
19 | 19 | #include "clang/Lex/Lexer.h"
|
| 20 | +#include "llvm/ADT/DenseSet.h" |
20 | 21 | #include "llvm/ADT/SmallSet.h"
|
21 | 22 | #include "llvm/ADT/StringExtras.h"
|
22 | 23 | #include "llvm/ProfileData/Coverage/CoverageMapping.h"
|
@@ -325,16 +326,26 @@ class CoverageMappingBuilder {
|
325 | 326 |
|
326 | 327 | llvm::SmallSet<FileID, 8> Visited;
|
327 | 328 | SmallVector<std::pair<SourceLocation, unsigned>, 8> FileLocs;
|
328 |
| - for (const auto &Region : SourceRegions) { |
| 329 | + for (auto &Region : SourceRegions) { |
329 | 330 | SourceLocation Loc = Region.getBeginLoc();
|
| 331 | + |
| 332 | + // Replace Loc with FileLoc if it is expanded with system headers. |
| 333 | + if (!SystemHeadersCoverage && SM.isInSystemMacro(Loc)) { |
| 334 | + auto BeginLoc = SM.getSpellingLoc(Loc); |
| 335 | + auto EndLoc = SM.getSpellingLoc(Region.getEndLoc()); |
| 336 | + if (SM.isWrittenInSameFile(BeginLoc, EndLoc)) { |
| 337 | + Loc = SM.getFileLoc(Loc); |
| 338 | + Region.setStartLoc(Loc); |
| 339 | + Region.setEndLoc(SM.getFileLoc(Region.getEndLoc())); |
| 340 | + } |
| 341 | + } |
| 342 | + |
330 | 343 | FileID File = SM.getFileID(Loc);
|
331 | 344 | if (!Visited.insert(File).second)
|
332 | 345 | continue;
|
333 | 346 |
|
334 |
| - // Do not map FileID's associated with system headers unless collecting |
335 |
| - // coverage from system headers is explicitly enabled. |
336 |
| - if (!SystemHeadersCoverage && SM.isInSystemHeader(SM.getSpellingLoc(Loc))) |
337 |
| - continue; |
| 347 | + assert(SystemHeadersCoverage || |
| 348 | + !SM.isInSystemHeader(SM.getSpellingLoc(Loc))); |
338 | 349 |
|
339 | 350 | unsigned Depth = 0;
|
340 | 351 | for (SourceLocation Parent = getIncludeOrExpansionLoc(Loc);
|
@@ -816,6 +827,10 @@ struct CounterCoverageMappingBuilder
|
816 | 827 | /// A stack of currently live regions.
|
817 | 828 | llvm::SmallVector<SourceMappingRegion> RegionStack;
|
818 | 829 |
|
| 830 | + /// Set if the Expr should be handled as a leaf even if it is kind of binary |
| 831 | + /// logical ops (&&, ||). |
| 832 | + llvm::DenseSet<const Stmt *> LeafExprSet; |
| 833 | + |
819 | 834 | /// An object to manage MCDC regions.
|
820 | 835 | MCDCCoverageBuilder MCDCBuilder;
|
821 | 836 |
|
@@ -1041,7 +1056,10 @@ struct CounterCoverageMappingBuilder
|
1041 | 1056 | // region onto RegionStack but immediately pop it (which adds it to the
|
1042 | 1057 | // function's SourceRegions) because it doesn't apply to any other source
|
1043 | 1058 | // code other than the Condition.
|
1044 |
| - if (CodeGenFunction::isInstrumentedCondition(C)) { |
| 1059 | + // With !SystemHeadersCoverage, binary logical ops in system headers may be |
| 1060 | + // treated as instrumentable conditions. |
| 1061 | + if (CodeGenFunction::isInstrumentedCondition(C) || |
| 1062 | + LeafExprSet.count(CodeGenFunction::stripCond(C))) { |
1045 | 1063 | MCDCConditionID ID = MCDCBuilder.getCondID(C);
|
1046 | 1064 | MCDCConditionID TrueID = IDPair.TrueID;
|
1047 | 1065 | MCDCConditionID FalseID = IDPair.FalseID;
|
@@ -1977,7 +1995,20 @@ struct CounterCoverageMappingBuilder
|
1977 | 1995 | subtractCounters(ParentCount, TrueCount));
|
1978 | 1996 | }
|
1979 | 1997 |
|
| 1998 | + /// Check if E belongs to system headers. |
| 1999 | + bool isExprInSystemHeader(const BinaryOperator *E) const { |
| 2000 | + return (!SystemHeadersCoverage && |
| 2001 | + SM.isInSystemHeader(SM.getSpellingLoc(E->getOperatorLoc())) && |
| 2002 | + SM.isInSystemHeader(SM.getSpellingLoc(E->getBeginLoc())) && |
| 2003 | + SM.isInSystemHeader(SM.getSpellingLoc(E->getEndLoc()))); |
| 2004 | + } |
| 2005 | + |
1980 | 2006 | void VisitBinLAnd(const BinaryOperator *E) {
|
| 2007 | + if (isExprInSystemHeader(E)) { |
| 2008 | + LeafExprSet.insert(E); |
| 2009 | + return; |
| 2010 | + } |
| 2011 | + |
1981 | 2012 | bool IsRootNode = MCDCBuilder.isIdle();
|
1982 | 2013 |
|
1983 | 2014 | // Keep track of Binary Operator and assign MCDC condition IDs.
|
@@ -2031,6 +2062,11 @@ struct CounterCoverageMappingBuilder
|
2031 | 2062 | }
|
2032 | 2063 |
|
2033 | 2064 | void VisitBinLOr(const BinaryOperator *E) {
|
| 2065 | + if (isExprInSystemHeader(E)) { |
| 2066 | + LeafExprSet.insert(E); |
| 2067 | + return; |
| 2068 | + } |
| 2069 | + |
2034 | 2070 | bool IsRootNode = MCDCBuilder.isIdle();
|
2035 | 2071 |
|
2036 | 2072 | // Keep track of Binary Operator and assign MCDC condition IDs.
|
|
0 commit comments