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());
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());
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits