summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Stellard <tstellar@redhat.com>2018-11-28 20:04:13 +0000
committerTom Stellard <tstellar@redhat.com>2018-11-28 20:04:13 +0000
commitf79f472aa167d5594584d0e340848df4c02e258c (patch)
tree82c38f694f900cf11aef643a85edd76967388b84
parentb948f5fe98da2c9eb3afc082adbca5dbd95ecb8f (diff)
downloadbcm5719-llvm-f79f472aa167d5594584d0e340848df4c02e258c.tar.gz
bcm5719-llvm-f79f472aa167d5594584d0e340848df4c02e258c.zip
Merging r347262:
------------------------------------------------------------------------ r347262 | vedantk | 2018-11-19 12:10:22 -0800 (Mon, 19 Nov 2018) | 8 lines [Coverage] Fix PR39258: support coverage regions that start deeper than they end popRegions used to assume that the start location of a region can't be nested deeper than the end location, which is not always true. Patch by Orivej Desh! Differential Revision: https://reviews.llvm.org/D53244 ------------------------------------------------------------------------ llvm-svn: 347798
-rw-r--r--clang/lib/CodeGen/CoverageMappingGen.cpp53
-rw-r--r--clang/test/CoverageMapping/macros.c10
2 files changed, 52 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp
index 389d29e467b..45a260b41d4 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -553,6 +553,15 @@ struct CounterCoverageMappingBuilder
completeDeferred(Count, DeferredEndLoc);
}
+ size_t locationDepth(SourceLocation Loc) {
+ size_t Depth = 0;
+ while (Loc.isValid()) {
+ Loc = getIncludeOrExpansionLoc(Loc);
+ Depth++;
+ }
+ return Depth;
+ }
+
/// Pop regions from the stack into the function's list of regions.
///
/// Adds all regions from \c ParentIndex to the top of the stack to the
@@ -567,19 +576,41 @@ struct CounterCoverageMappingBuilder
SourceLocation EndLoc = Region.hasEndLoc()
? Region.getEndLoc()
: RegionStack[ParentIndex].getEndLoc();
+ size_t StartDepth = locationDepth(StartLoc);
+ size_t EndDepth = locationDepth(EndLoc);
while (!SM.isWrittenInSameFile(StartLoc, EndLoc)) {
- // The region ends in a nested file or macro expansion. Create a
- // separate region for each expansion.
- SourceLocation NestedLoc = getStartOfFileOrMacro(EndLoc);
- assert(SM.isWrittenInSameFile(NestedLoc, EndLoc));
-
- if (!isRegionAlreadyAdded(NestedLoc, EndLoc))
- SourceRegions.emplace_back(Region.getCounter(), NestedLoc, EndLoc);
-
- EndLoc = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(EndLoc));
- if (EndLoc.isInvalid())
- llvm::report_fatal_error("File exit not handled before popRegions");
+ bool UnnestStart = StartDepth >= EndDepth;
+ bool UnnestEnd = EndDepth >= StartDepth;
+ if (UnnestEnd) {
+ // The region ends in a nested file or macro expansion. Create a
+ // separate region for each expansion.
+ SourceLocation NestedLoc = getStartOfFileOrMacro(EndLoc);
+ assert(SM.isWrittenInSameFile(NestedLoc, EndLoc));
+
+ if (!isRegionAlreadyAdded(NestedLoc, EndLoc))
+ SourceRegions.emplace_back(Region.getCounter(), NestedLoc, EndLoc);
+
+ EndLoc = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(EndLoc));
+ if (EndLoc.isInvalid())
+ llvm::report_fatal_error("File exit not handled before popRegions");
+ EndDepth--;
+ }
+ if (UnnestStart) {
+ // The region begins in a nested file or macro expansion. Create a
+ // separate region for each expansion.
+ SourceLocation NestedLoc = getEndOfFileOrMacro(StartLoc);
+ assert(SM.isWrittenInSameFile(StartLoc, NestedLoc));
+
+ if (!isRegionAlreadyAdded(StartLoc, NestedLoc))
+ SourceRegions.emplace_back(Region.getCounter(), StartLoc, NestedLoc);
+
+ StartLoc = getIncludeOrExpansionLoc(StartLoc);
+ if (StartLoc.isInvalid())
+ llvm::report_fatal_error("File exit not handled before popRegions");
+ StartDepth--;
+ }
}
+ Region.setStartLoc(StartLoc);
Region.setEndLoc(EndLoc);
MostRecentLocation = EndLoc;
diff --git a/clang/test/CoverageMapping/macros.c b/clang/test/CoverageMapping/macros.c
index 95fe37ed7e8..39cd190b2a8 100644
--- a/clang/test/CoverageMapping/macros.c
+++ b/clang/test/CoverageMapping/macros.c
@@ -4,6 +4,7 @@
#define MACRO_2 bar()
#define MACRO_1 return; MACRO_2
#define MACRO_3 MACRO_2
+#define GOTO goto
void bar() {}
@@ -56,6 +57,15 @@ void func5() { // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+4]]:2 = #0
// CHECK-NEXT: Expansion,File 1, 6:17 -> 6:24 = #1
// CHECK-NEXT: File 2, 4:17 -> 4:22 = #1
+// CHECK-NEXT: func6
+void func6(unsigned count) { // CHECK-NEXT: File 0, [[@LINE]]:28 -> [[@LINE+4]]:2 = #0
+begin: // CHECK-NEXT: File 0, [[@LINE]]:1 -> [[@LINE+3]]:2 = #1
+ if (count--) // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:16 = #1
+ GOTO begin; // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:19 = #2
+}
+// CHECK-NEXT: Expansion,File 0, [[@LINE-2]]:9 -> [[@LINE-2]]:13 = #2
+// CHECK-NEXT: File 1, 7:14 -> 7:18 = #2
+
int main(int argc, const char *argv[]) {
func();
func2();
OpenPOWER on IntegriCloud