summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CoverageMappingGen.cpp
diff options
context:
space:
mode:
authorIgor Kudrin <ikudrin.dev@gmail.com>2016-06-07 02:17:03 +0000
committerIgor Kudrin <ikudrin.dev@gmail.com>2016-06-07 02:17:03 +0000
commitf962670a08ef14c8bc5eeeb991078593e0c2ae20 (patch)
treee28c59594025ec4768e60be8d285d57dcd6f9e98 /lib/CodeGen/CoverageMappingGen.cpp
parent01203ed48e7813969a5995d2b57df6d31dec63ae (diff)
[Coverage] Fix an assertion failure if the definition of an unused function spans multiple files.
We have an assertion failure if, for example, the definition of an unused inline function starts in one macro and ends in another. This patch fixes the issue by finding the common ancestor of the start and end locations of that function's body and changing the locations accordingly. Differential Revision: http://reviews.llvm.org/D20997 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@271969 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CoverageMappingGen.cpp')
-rw-r--r--lib/CodeGen/CoverageMappingGen.cpp42
1 files changed, 31 insertions, 11 deletions
diff --git a/lib/CodeGen/CoverageMappingGen.cpp b/lib/CodeGen/CoverageMappingGen.cpp
index bd34e1c5a8..44c90e30cd 100644
--- a/lib/CodeGen/CoverageMappingGen.cpp
+++ b/lib/CodeGen/CoverageMappingGen.cpp
@@ -130,6 +130,16 @@ public:
return strcmp(SM.getBufferName(SM.getSpellingLoc(Loc)), "<built-in>") == 0;
}
+ /// \brief Check whether \c Loc is included or expanded from \c Parent.
+ bool isNestedIn(SourceLocation Loc, FileID Parent) {
+ do {
+ Loc = getIncludeOrExpansionLoc(Loc);
+ if (Loc.isInvalid())
+ return false;
+ } while (!SM.isInFileID(Loc, Parent));
+ return true;
+ }
+
/// \brief Get the start of \c S ignoring macro arguments and builtin macros.
SourceLocation getStart(const Stmt *S) {
SourceLocation Loc = S->getLocStart();
@@ -310,7 +320,27 @@ struct EmptyCoverageMappingBuilder : public CoverageMappingBuilder {
if (!D->hasBody())
return;
auto Body = D->getBody();
- SourceRegions.emplace_back(Counter(), getStart(Body), getEnd(Body));
+ SourceLocation Start = getStart(Body);
+ SourceLocation End = getEnd(Body);
+ if (!SM.isWrittenInSameFile(Start, End)) {
+ // Walk up to find the common ancestor.
+ // Correct the locations accordingly.
+ FileID StartFileID = SM.getFileID(Start);
+ FileID EndFileID = SM.getFileID(End);
+ while (StartFileID != EndFileID && !isNestedIn(End, StartFileID)) {
+ Start = getIncludeOrExpansionLoc(Start);
+ assert(Start.isValid() &&
+ "Declaration start location not nested within a known region");
+ StartFileID = SM.getFileID(Start);
+ }
+ while (StartFileID != EndFileID) {
+ End = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(End));
+ assert(End.isValid() &&
+ "Declaration end location not nested within a known region");
+ EndFileID = SM.getFileID(End);
+ }
+ }
+ SourceRegions.emplace_back(Counter(), Start, End);
}
/// \brief Write the mapping data to the output stream
@@ -471,16 +501,6 @@ struct CounterCoverageMappingBuilder
MostRecentLocation = getIncludeOrExpansionLoc(MostRecentLocation);
}
- /// \brief Check whether \c Loc is included or expanded from \c Parent.
- bool isNestedIn(SourceLocation Loc, FileID Parent) {
- do {
- Loc = getIncludeOrExpansionLoc(Loc);
- if (Loc.isInvalid())
- return false;
- } while (!SM.isInFileID(Loc, Parent));
- return true;
- }
-
/// \brief Adjust regions and state when \c NewLoc exits a file.
///
/// If moving from our most recently tracked location to \c NewLoc exits any