Skip to content

Commit

Permalink
[coverage] Special-case calls to noreturn functions.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Eli Friedman committed Aug 8, 2017
1 parent 8a813cf commit 181dfe4
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 0 deletions.
10 changes: 10 additions & 0 deletions clang/lib/CodeGen/CoverageMappingGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
11 changes: 11 additions & 0 deletions clang/test/CoverageMapping/md.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
13 changes: 13 additions & 0 deletions clang/test/CoverageMapping/switch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

0 comments on commit 181dfe4

Please sign in to comment.