r268511 - [Coverage] Fix an issue where a coverage region might not be created for a macro containing a loop statement.

Igor Kudrin via cfe-commits cfe-commits at lists.llvm.org
Wed May 4 08:38:27 PDT 2016


Author: ikudrin
Date: Wed May  4 10:38:26 2016
New Revision: 268511

URL: http://llvm.org/viewvc/llvm-project?rev=268511&view=rev
Log:
[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

Modified:
    cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp
    cfe/trunk/test/CoverageMapping/macroscopes.cpp

Modified: cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp?rev=268511&r1=268510&r2=268511&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp (original)
+++ cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp Wed May  4 10:38:26 2016
@@ -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);
   }
 

Modified: cfe/trunk/test/CoverageMapping/macroscopes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CoverageMapping/macroscopes.cpp?rev=268511&r1=268510&r2=268511&view=diff
==============================================================================
--- cfe/trunk/test/CoverageMapping/macroscopes.cpp (original)
+++ cfe/trunk/test/CoverageMapping/macroscopes.cpp Wed May  4 10:38:26 2016
@@ -22,6 +22,17 @@
 #define starts_a_while while (x < 5)
 #define simple_stmt ++x
 
+#define macro_with_for          \
+  x = 3;                        \
+  for (int i = 0; i < x; ++i) { \
+  }
+
+#define macro_with_while \
+  x = 4;                 \
+  while (x < 5) {        \
+    ++x;                 \
+  }
+
 // CHECK: main
 // CHECK-NEXT: File 0, [[@LINE+1]]:12 -> {{[0-9]+}}:2 = #0
 int main() {
@@ -64,6 +75,11 @@ int main() {
     simple_stmt;
   ends_a_scope
 
+  // CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:17 = #0
+  macro_with_for
+  // CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:19 = #0
+  macro_with_while
+
   return 0;
 }
 
@@ -103,3 +119,10 @@ int main() {
 // CHECK-NEXT: File 11, 22:31 -> 22:36 = (#0 + #9)
 // CHECK-NEXT: File 12, 23:21 -> 23:24 = #9
 // CHECK-NEXT: File 13, 6:3 -> 7:4 = #9
+// CHECK-NEXT: File 14, 26:3 -> 28:4 = #0
+// CHECK-NEXT: File 14, 27:19 -> 27:24 = (#0 + #10)
+// CHECK-NEXT: File 14, 27:26 -> 27:29 = #10
+// CHECK-NEXT: File 14, 27:31 -> 28:4 = #10
+// CHECK-NEXT: File 15, 31:3 -> 34:4 = #0
+// CHECK-NEXT: File 15, 32:10 -> 32:15 = (#0 + #11)
+// CHECK-NEXT: File 15, 32:17 -> 34:4 = #11




More information about the cfe-commits mailing list