aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CoverageMappingGen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CoverageMappingGen.cpp')
-rw-r--r--clang/lib/CodeGen/CoverageMappingGen.cpp22
1 files changed, 19 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp
index 820ba1b..d3fd19c 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -443,15 +443,31 @@ struct CounterCoverageMappingBuilder
return ExitCount;
}
+ /// \brief Check whether a region with bounds \c StartLoc and \c EndLoc
+ /// is already added to \c SourceRegions.
+ bool isRegionAlreadyAdded(SourceLocation StartLoc, SourceLocation EndLoc) {
+ return SourceRegions.rend() !=
+ std::find_if(SourceRegions.rbegin(), SourceRegions.rend(),
+ [&](const SourceMappingRegion &Region) {
+ return Region.getStartLoc() == StartLoc &&
+ Region.getEndLoc() == EndLoc;
+ });
+ }
+
/// \brief Adjust the most recently visited location to \c EndLoc.
///
/// This should be used after visiting any statements in non-source order.
void adjustForOutOfOrderTraversal(SourceLocation EndLoc) {
MostRecentLocation = EndLoc;
- // Avoid adding duplicate regions if we have a completed region on the top
- // of the stack and are adjusting to the end of a virtual file.
+ // The code region for a whole macro is created in handleFileExit() when
+ // it detects exiting of the virtual file of that macro. If we visited
+ // statements in non-source order, we might already have such a region
+ // added, for example, if a body of a loop is divided among multiple
+ // macros. Avoid adding duplicate regions in such case.
if (getRegion().hasEndLoc() &&
- MostRecentLocation == getEndOfFileOrMacro(MostRecentLocation))
+ MostRecentLocation == getEndOfFileOrMacro(MostRecentLocation) &&
+ isRegionAlreadyAdded(getStartOfFileOrMacro(MostRecentLocation),
+ MostRecentLocation))
MostRecentLocation = getIncludeOrExpansionLoc(MostRecentLocation);
}