[coverage] Special-case calls to noreturn functions.

The code after a noreturn call doesn't execute.

The pattern in the testcase is pretty common in LLVM (a switch with
a default case that calls llvm_unreachable).

The original version of this patch was reverted in r309995 due to a
crash. This version includes a fix for that crash (testcase in 
test/CoverageMapping/md.cpp).

Differential Revision: https://reviews.llvm.org/D36250

llvm-svn: 310406
This commit is contained in:
Eli Friedman 2017-08-08 20:10:14 +00:00
parent 8a813cf646
commit 181dfe4c92
3 changed files with 34 additions and 0 deletions

View File

@ -716,6 +716,16 @@ struct CounterCoverageMappingBuilder
terminateRegion(S);
}
void VisitCallExpr(const CallExpr *E) {
VisitStmt(E);
// Terminate the region when we hit a noreturn function.
// (This is helpful dealing with switch statements.)
QualType CalleeType = E->getCallee()->getType();
if (getFunctionExtInfo(*CalleeType).getNoReturn())
terminateRegion(E);
}
void VisitWhileStmt(const WhileStmt *S) {
extendRegion(S);

View File

@ -27,6 +27,17 @@ void foo(MD i) {
#include "Inputs/md.def"
}
// CHECK: bar
// CHECK-NEXT: File 0, [[@LINE+3]]:12 -> [[@LINE+8]]:2 = #0
bool isVal1();
bool isVal2();
bool bar() {
#define HANDLE_MD(X) is##X() ||
return
#include "Inputs/md.def"
0;
}
int main(int argc, const char *argv[]) {
foo(MD::Val1);
return 0;

View File

@ -97,3 +97,16 @@ int fallthrough(int i) { // CHECK-NEXT: File 0, [[@LINE]]:24 -> [[@LINE+12]]:2 =
break;
}
}
void abort(void) __attribute((noreturn));
// CHECK: noret
int noret(int x) { // CHECK-NEXT: File 0, [[@LINE]]:18 -> [[@LINE+9]]:2
switch (x) {
default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:12
abort();
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:13
return 5;
case 2: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:14
return 10;
}
}