|
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"
|
@@ -336,16 +337,26 @@ class CoverageMappingBuilder {
|
336 | 337 |
|
337 | 338 | llvm::SmallSet<FileID, 8> Visited;
|
338 | 339 | SmallVector<std::pair<SourceLocation, unsigned>, 8> FileLocs;
|
339 |
| - for (const auto &Region : SourceRegions) { |
| 340 | + for (auto &Region : SourceRegions) { |
340 | 341 | SourceLocation Loc = Region.getBeginLoc();
|
| 342 | + |
| 343 | + // Replace Loc with FileLoc if it is expanded with system headers. |
| 344 | + if (!SystemHeadersCoverage && SM.isInSystemMacro(Loc)) { |
| 345 | + auto BeginLoc = SM.getSpellingLoc(Loc); |
| 346 | + auto EndLoc = SM.getSpellingLoc(Region.getEndLoc()); |
| 347 | + if (SM.isWrittenInSameFile(BeginLoc, EndLoc)) { |
| 348 | + Loc = SM.getFileLoc(Loc); |
| 349 | + Region.setStartLoc(Loc); |
| 350 | + Region.setEndLoc(SM.getFileLoc(Region.getEndLoc())); |
| 351 | + } |
| 352 | + } |
| 353 | + |
341 | 354 | FileID File = SM.getFileID(Loc);
|
342 | 355 | if (!Visited.insert(File).second)
|
343 | 356 | continue;
|
344 | 357 |
|
345 |
| - // Do not map FileID's associated with system headers unless collecting |
346 |
| - // coverage from system headers is explicitly enabled. |
347 |
| - if (!SystemHeadersCoverage && SM.isInSystemHeader(SM.getSpellingLoc(Loc))) |
348 |
| - continue; |
| 358 | + assert(SystemHeadersCoverage || |
| 359 | + !SM.isInSystemHeader(SM.getSpellingLoc(Loc))); |
349 | 360 |
|
350 | 361 | unsigned Depth = 0;
|
351 | 362 | for (SourceLocation Parent = getIncludeOrExpansionLoc(Loc);
|
@@ -818,6 +829,10 @@ struct CounterCoverageMappingBuilder
|
818 | 829 | /// A stack of currently live regions.
|
819 | 830 | llvm::SmallVector<SourceMappingRegion> RegionStack;
|
820 | 831 |
|
| 832 | + /// Set if the Expr should be handled as a leaf even if it is kind of binary |
| 833 | + /// logical ops (&&, ||). |
| 834 | + llvm::DenseSet<const Stmt *> LeafExprSet; |
| 835 | + |
821 | 836 | /// An object to manage MCDC regions.
|
822 | 837 | MCDCCoverageBuilder MCDCBuilder;
|
823 | 838 |
|
@@ -1040,7 +1055,10 @@ struct CounterCoverageMappingBuilder
|
1040 | 1055 | // region onto RegionStack but immediately pop it (which adds it to the
|
1041 | 1056 | // function's SourceRegions) because it doesn't apply to any other source
|
1042 | 1057 | // code other than the Condition.
|
1043 |
| - if (CodeGenFunction::isInstrumentedCondition(C)) { |
| 1058 | + // With !SystemHeadersCoverage, binary logical ops in system headers may be |
| 1059 | + // treated as instrumentable conditions. |
| 1060 | + if (CodeGenFunction::isInstrumentedCondition(C) || |
| 1061 | + LeafExprSet.count(CodeGenFunction::stripCond(C))) { |
1044 | 1062 | mcdc::Parameters BranchParams;
|
1045 | 1063 | mcdc::ConditionID ID = MCDCBuilder.getCondID(C);
|
1046 | 1064 | if (ID >= 0)
|
@@ -2070,7 +2088,20 @@ struct CounterCoverageMappingBuilder
|
2070 | 2088 | createDecisionRegion(E, DecisionParams);
|
2071 | 2089 | }
|
2072 | 2090 |
|
| 2091 | + /// Check if E belongs to system headers. |
| 2092 | + bool isExprInSystemHeader(const BinaryOperator *E) const { |
| 2093 | + return (!SystemHeadersCoverage && |
| 2094 | + SM.isInSystemHeader(SM.getSpellingLoc(E->getOperatorLoc())) && |
| 2095 | + SM.isInSystemHeader(SM.getSpellingLoc(E->getBeginLoc())) && |
| 2096 | + SM.isInSystemHeader(SM.getSpellingLoc(E->getEndLoc()))); |
| 2097 | + } |
| 2098 | + |
2073 | 2099 | void VisitBinLAnd(const BinaryOperator *E) {
|
| 2100 | + if (isExprInSystemHeader(E)) { |
| 2101 | + LeafExprSet.insert(E); |
| 2102 | + return; |
| 2103 | + } |
| 2104 | + |
2074 | 2105 | bool IsRootNode = MCDCBuilder.isIdle();
|
2075 | 2106 |
|
2076 | 2107 | // Keep track of Binary Operator and assign MCDC condition IDs.
|
@@ -2125,6 +2156,11 @@ struct CounterCoverageMappingBuilder
|
2125 | 2156 | }
|
2126 | 2157 |
|
2127 | 2158 | void VisitBinLOr(const BinaryOperator *E) {
|
| 2159 | + if (isExprInSystemHeader(E)) { |
| 2160 | + LeafExprSet.insert(E); |
| 2161 | + return; |
| 2162 | + } |
| 2163 | + |
2128 | 2164 | bool IsRootNode = MCDCBuilder.isIdle();
|
2129 | 2165 |
|
2130 | 2166 | // Keep track of Binary Operator and assign MCDC condition IDs.
|
|
0 commit comments