|
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"
|
@@ -339,16 +340,26 @@ class CoverageMappingBuilder {
|
339 | 340 |
|
340 | 341 | llvm::SmallSet<FileID, 8> Visited;
|
341 | 342 | SmallVector<std::pair<SourceLocation, unsigned>, 8> FileLocs;
|
342 |
| - for (const auto &Region : SourceRegions) { |
| 343 | + for (auto &Region : SourceRegions) { |
343 | 344 | SourceLocation Loc = Region.getBeginLoc();
|
| 345 | + |
| 346 | + // Replace Loc with FileLoc if it is expanded with system headers. |
| 347 | + if (!SystemHeadersCoverage && SM.isInSystemMacro(Loc)) { |
| 348 | + auto BeginLoc = SM.getSpellingLoc(Loc); |
| 349 | + auto EndLoc = SM.getSpellingLoc(Region.getEndLoc()); |
| 350 | + if (SM.isWrittenInSameFile(BeginLoc, EndLoc)) { |
| 351 | + Loc = SM.getFileLoc(Loc); |
| 352 | + Region.setStartLoc(Loc); |
| 353 | + Region.setEndLoc(SM.getFileLoc(Region.getEndLoc())); |
| 354 | + } |
| 355 | + } |
| 356 | + |
344 | 357 | FileID File = SM.getFileID(Loc);
|
345 | 358 | if (!Visited.insert(File).second)
|
346 | 359 | continue;
|
347 | 360 |
|
348 |
| - // Do not map FileID's associated with system headers unless collecting |
349 |
| - // coverage from system headers is explicitly enabled. |
350 |
| - if (!SystemHeadersCoverage && SM.isInSystemHeader(SM.getSpellingLoc(Loc))) |
351 |
| - continue; |
| 361 | + assert(SystemHeadersCoverage || |
| 362 | + !SM.isInSystemHeader(SM.getSpellingLoc(Loc))); |
352 | 363 |
|
353 | 364 | unsigned Depth = 0;
|
354 | 365 | for (SourceLocation Parent = getIncludeOrExpansionLoc(Loc);
|
@@ -821,6 +832,10 @@ struct CounterCoverageMappingBuilder
|
821 | 832 | /// A stack of currently live regions.
|
822 | 833 | llvm::SmallVector<SourceMappingRegion> RegionStack;
|
823 | 834 |
|
| 835 | + /// Set if the Expr should be handled as a leaf even if it is kind of binary |
| 836 | + /// logical ops (&&, ||). |
| 837 | + llvm::DenseSet<const Stmt *> LeafExprSet; |
| 838 | + |
824 | 839 | /// An object to manage MCDC regions.
|
825 | 840 | MCDCCoverageBuilder MCDCBuilder;
|
826 | 841 |
|
@@ -1043,7 +1058,10 @@ struct CounterCoverageMappingBuilder
|
1043 | 1058 | // region onto RegionStack but immediately pop it (which adds it to the
|
1044 | 1059 | // function's SourceRegions) because it doesn't apply to any other source
|
1045 | 1060 | // code other than the Condition.
|
1046 |
| - if (CodeGenFunction::isInstrumentedCondition(C)) { |
| 1061 | + // With !SystemHeadersCoverage, binary logical ops in system headers may be |
| 1062 | + // treated as instrumentable conditions. |
| 1063 | + if (CodeGenFunction::isInstrumentedCondition(C) || |
| 1064 | + LeafExprSet.count(CodeGenFunction::stripCond(C))) { |
1047 | 1065 | mcdc::Parameters BranchParams;
|
1048 | 1066 | mcdc::ConditionID ID = MCDCBuilder.getCondID(C);
|
1049 | 1067 | if (ID >= 0)
|
@@ -2064,7 +2082,20 @@ struct CounterCoverageMappingBuilder
|
2064 | 2082 | createDecisionRegion(E, DecisionParams);
|
2065 | 2083 | }
|
2066 | 2084 |
|
| 2085 | + /// Check if E belongs to system headers. |
| 2086 | + bool isExprInSystemHeader(const BinaryOperator *E) const { |
| 2087 | + return (!SystemHeadersCoverage && |
| 2088 | + SM.isInSystemHeader(SM.getSpellingLoc(E->getOperatorLoc())) && |
| 2089 | + SM.isInSystemHeader(SM.getSpellingLoc(E->getBeginLoc())) && |
| 2090 | + SM.isInSystemHeader(SM.getSpellingLoc(E->getEndLoc()))); |
| 2091 | + } |
| 2092 | + |
2067 | 2093 | void VisitBinLAnd(const BinaryOperator *E) {
|
| 2094 | + if (isExprInSystemHeader(E)) { |
| 2095 | + LeafExprSet.insert(E); |
| 2096 | + return; |
| 2097 | + } |
| 2098 | + |
2068 | 2099 | bool IsRootNode = MCDCBuilder.isIdle();
|
2069 | 2100 |
|
2070 | 2101 | // Keep track of Binary Operator and assign MCDC condition IDs.
|
@@ -2119,6 +2150,11 @@ struct CounterCoverageMappingBuilder
|
2119 | 2150 | }
|
2120 | 2151 |
|
2121 | 2152 | void VisitBinLOr(const BinaryOperator *E) {
|
| 2153 | + if (isExprInSystemHeader(E)) { |
| 2154 | + LeafExprSet.insert(E); |
| 2155 | + return; |
| 2156 | + } |
| 2157 | + |
2122 | 2158 | bool IsRootNode = MCDCBuilder.isIdle();
|
2123 | 2159 |
|
2124 | 2160 | // Keep track of Binary Operator and assign MCDC condition IDs.
|
|
0 commit comments