 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
68.8% |
11 / 16 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
87.5% |
14 / 16 |
| |
|
Line Coverage: |
100.0% |
21 / 21 |
| |
 |
|
 |
1 : //=== NoReturnFunctionChecker.cpp -------------------------------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This defines NoReturnFunctionChecker, which evaluates functions that do not
11 : // return to the caller.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #include "GRExprEngineInternalChecks.h"
16 : #include "clang/Checker/PathSensitive/Checker.h"
17 : #include "llvm/ADT/StringSwitch.h"
18 :
19 : using namespace clang;
20 :
21 : namespace {
22 :
2138: branch 2 taken
0: branch 3 not taken
0: branch 6 not taken
0: branch 7 not taken
23 4276: class NoReturnFunctionChecker : public Checker {
24 : public:
25 2138: static void *getTag() { static int tag = 0; return &tag; }
26 : virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
27 : };
28 :
29 : }
30 :
31 2138: void clang::RegisterNoReturnFunctionChecker(GRExprEngine &Eng) {
32 2138: Eng.registerCheck(new NoReturnFunctionChecker());
33 2138: }
34 :
35 : bool NoReturnFunctionChecker::EvalCallExpr(CheckerContext &C,
36 1646: const CallExpr *CE) {
37 1646: const GRState *state = C.getState();
38 1646: const Expr *Callee = CE->getCallee();
39 1646: SVal L = state->getSVal(Callee);
40 1646: const FunctionDecl *FD = L.getAsFunctionDecl();
56: branch 0 taken
1590: branch 1 taken
41 1646: if (!FD)
42 56: return false;
43 :
44 1590: bool BuildSinks = false;
45 :
1590: branch 1 taken
0: branch 2 not taken
10: branch 4 taken
1580: branch 5 taken
10: branch 6 taken
1580: branch 7 taken
46 1590: if (FD->getAttr<NoReturnAttr>() || FD->getAttr<AnalyzerNoReturnAttr>())
47 10: BuildSinks = true;
1580: branch 1 taken
0: branch 2 not taken
48 1580: else if (const IdentifierInfo *II = FD->getIdentifier()) {
49 : // HACK: Some functions are not marked noreturn, and don't return.
50 : // Here are a few hardwired ones. If this takes too long, we can
51 : // potentially cache these results.
52 : BuildSinks
53 : = llvm::StringSwitch<bool>(llvm::StringRef(II->getName()))
54 : .Case("exit", true)
55 : .Case("panic", true)
56 : .Case("error", true)
57 : .Case("Assert", true)
58 : // FIXME: This is just a wrapper around throwing an exception.
59 : // Eventually inter-procedural analysis should handle this easily.
60 : .Case("ziperr", true)
61 : .Case("assfail", true)
62 : .Case("db_error", true)
63 : .Case("__assert", true)
64 : .Case("__assert_rtn", true)
65 : .Case("__assert_fail", true)
66 : .Case("dtrace_assfail", true)
67 : .Case("yy_fatal_error", true)
68 : .Case("_XCAssertionFailureHandler", true)
69 : .Case("_DTAssertionFailureHandler", true)
70 : .Case("_TSAssertionFailureHandler", true)
71 1580: .Default(false);
72 : }
73 :
1564: branch 0 taken
26: branch 1 taken
74 1590: if (!BuildSinks)
75 1564: return false;
76 :
77 26: C.GenerateSink(CE);
78 26: return true;
79 : }
Generated: 2010-02-10 01:31 by zcov