[PATCH] D16934: [Coverage] Fix crash in VisitIfStmt

Vedant Kumar via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 5 14:23:41 PST 2016


vsk created this revision.
vsk added a reviewer: bogner.
vsk added a subscriber: cfe-commits.

When handling 'if' statements, we crash if the condition and the consequent
branch are spanned by a single macro expansion.

The crash occurs because of a sanity 'reset' in `popRegions()`: if an expansion
exactly spans an entire region, we set `MostRecentLocation` to the start of the
expansion (its 'include location').  This ensures we don't `handleFileExit()`
ourselves out of the expansion before we're done processing all of the regions
within it. This is tested in test/CoverageMapping/macro-expressions.c.

This causes a problem when an expansion spans both the condition and the
consequent branch of an 'if' statement. `MostRecentLocation` is updated to the
start of the 'if' statement in `popRegions()`, so the file for the expansion
isn't exited by the time we're done handling the statement. We then crash with
'fatal: File exit not handled before popRegions'.

The fix for this is to detect these kinds of expansions, and conservatively
update `MostRecentLocation` to the end of expansion region containing the
conditional. I've added tests to make sure we don't have the same problem with
other kinds of statements.

rdar://problem/23630316

http://reviews.llvm.org/D16934

Files:
  lib/CodeGen/CoverageMappingGen.cpp
  test/CoverageMapping/macro-expressions.cpp

Index: test/CoverageMapping/macro-expressions.cpp
===================================================================
--- test/CoverageMapping/macro-expressions.cpp
+++ test/CoverageMapping/macro-expressions.cpp
@@ -12,6 +12,38 @@
 #define PRIo64 PRI_64_LENGTH_MODIFIER "o"
 #define PRIu64 PRI_64_LENGTH_MODIFIER "u"
 
+#define STMT(s) s
+
+void fn1() {
+  STMT(if (1));
+  STMT(while (1));
+  STMT(for (;;));
+  if (1)
+    STMT(if (1)) 0;
+  if (1)
+    STMT(while (1)) 0;
+  if (1)
+    STMT(for (;;)) 0;
+  while (1)
+    STMT(if (1)) 0;
+  while (1)
+    STMT(while (1)) 0;
+  while (1)
+    STMT(for (;;)) 0;
+  for (;;)
+    STMT(if (1)) 0;
+  for (;;)
+    STMT(while (1)) 0;
+  for (;;)
+    STMT(for (;;)) 0;
+}
+
+void STMT(fn2()) {
+}
+
+void STMT(fn3)() {
+}
+
 // CHECK: foo
 // CHECK-NEXT: File 0, [[@LINE+1]]:17 -> {{[0-9]+}}:2 = #0
 void foo(int i) {
Index: lib/CodeGen/CoverageMappingGen.cpp
===================================================================
--- lib/CodeGen/CoverageMappingGen.cpp
+++ lib/CodeGen/CoverageMappingGen.cpp
@@ -807,6 +807,14 @@
     // counter for the body when looking at the coverage.
     propagateCounts(ParentCount, S->getCond());
 
+    // The region containing the condition may be spanned by an expansion.
+    // Make sure we handle a file exit out of this expansion before handling
+    // the consequent branch.
+    if (SM.isBeforeInTranslationUnit(getStart(S->getCond()),
+                                     S->getCond()->getLocStart())) {
+      MostRecentLocation = getEnd(S->getCond());
+    }
+
     extendRegion(S->getThen());
     Counter OutCount = propagateCounts(ThenCount, S->getThen());
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D16934.47048.patch
Type: text/x-patch
Size: 1664 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160205/31a0c04b/attachment-0001.bin>


More information about the cfe-commits mailing list