[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