zcov: / lib/Checker/NoReturnFunctionChecker.cpp


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


Programs: 1 Runs 2897


       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