]> granicus.if.org Git - clang/commitdiff
[Coverage] Fix crash when handling certain macro expansions
authorVedant Kumar <vsk@apple.com>
Mon, 8 Feb 2016 19:25:45 +0000 (19:25 +0000)
committerVedant Kumar <vsk@apple.com>
Mon, 8 Feb 2016 19:25:45 +0000 (19:25 +0000)
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

Differential Revision: http://reviews.llvm.org/D16934

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@260129 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 2fa6f27c5afe226ac811975e90930d3f361cb5c3..9279d1a37cfedf97a89dd366a90909de9d3ad5fc 100644 (file)
@@ -434,6 +434,12 @@ struct CounterCoverageMappingBuilder
     Visit(S);
     Counter ExitCount = getRegion().getCounter();
     popRegions(Index);
+
+    // The statement may be spanned by an expansion. Make sure we handle a file
+    // exit out of this expansion before moving to the next statement.
+    if (SM.isBeforeInTranslationUnit(getStart(S), S->getLocStart()))
+      MostRecentLocation = getEnd(S);
+
     return ExitCount;
   }
 
index 6626bfefd6c42e673d68f8d233e1e524a771f19d..3852fc6a23b7d69268619fccafc7e95dc0e57324 100644 (file)
 #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 (;;));
+  STMT(if) (1);
+  STMT(while) (1);
+  STMT(for) (;;);
+  if (1)
+    STMT(if (1)
+        STMT(if (1)));
+  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) {