From: Eli Friedman Date: Tue, 8 Aug 2017 20:10:14 +0000 (+0000) Subject: [coverage] Special-case calls to noreturn functions. X-Git-Tag: llvmorg-6.0.0-rc1~10577 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=181dfe4c92ad2671a4ff5c2d91d927dd5a9958b8;p=platform%2Fupstream%2Fllvm.git [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 --- diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 1484ec7..f2e051c 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -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); diff --git a/clang/test/CoverageMapping/md.cpp b/clang/test/CoverageMapping/md.cpp index 20c696c..5f2b2d6 100644 --- a/clang/test/CoverageMapping/md.cpp +++ b/clang/test/CoverageMapping/md.cpp @@ -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; diff --git a/clang/test/CoverageMapping/switch.cpp b/clang/test/CoverageMapping/switch.cpp index 17aa53b..52f22e8 100644 --- a/clang/test/CoverageMapping/switch.cpp +++ b/clang/test/CoverageMapping/switch.cpp @@ -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; + } +}