diff options
author | Igor Kudrin <ikudrin.dev@gmail.com> | 2016-05-04 15:38:26 +0000 |
---|---|---|
committer | Igor Kudrin <ikudrin.dev@gmail.com> | 2016-05-04 15:38:26 +0000 |
commit | 0a7c9d110c9e755c535741d42dfc4c266e3aee7b (patch) | |
tree | e8ec6c8817419880fd39a4bf3a59bb2cba46343f /clang/lib | |
parent | 96051a4efc763e559ba8f115c8133e6847ccec70 (diff) | |
download | bcm5719-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.cpp | 22 |
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); } |