summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorIgor Kudrin <ikudrin.dev@gmail.com>2016-05-04 15:38:26 +0000
committerIgor Kudrin <ikudrin.dev@gmail.com>2016-05-04 15:38:26 +0000
commit0a7c9d110c9e755c535741d42dfc4c266e3aee7b (patch)
treee8ec6c8817419880fd39a4bf3a59bb2cba46343f /clang/lib
parent96051a4efc763e559ba8f115c8133e6847ccec70 (diff)
downloadbcm5719-llvm-0a7c9d110c9e755c535741d42dfc4c266e3aee7b.tar.gz
bcm5719-llvm-0a7c9d110c9e755c535741d42dfc4c266e3aee7b.zip
[Coverage] Fix an issue where a coverage region might not be created for a macro containing a loop statement.
The issue happened when a macro contained a full for or while statement, which body ended at the end of the macro. Differential Revision: http://reviews.llvm.org/D19725 llvm-svn: 268511
Diffstat (limited to 'clang/lib')
-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 820ba1b8f72..d3fd19c1745 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);
}
OpenPOWER on IntegriCloud