diff options
| author | Ted Kremenek <kremenek@apple.com> | 2010-03-26 22:57:13 +0000 | 
|---|---|---|
| committer | Ted Kremenek <kremenek@apple.com> | 2010-03-26 22:57:13 +0000 | 
| commit | 0f250e4c5be629d58fe833a9e18585a19a29c19d (patch) | |
| tree | 5a3a4b38a63a15f98d063c522866cd5ef161c923 /clang/lib | |
| parent | ee0934e05d202887054d1e2887d224e53464da50 (diff) | |
| download | bcm5719-llvm-0f250e4c5be629d58fe833a9e18585a19a29c19d.tar.gz bcm5719-llvm-0f250e4c5be629d58fe833a9e18585a19a29c19d.zip  | |
Fix NoReturnFunctionChecker to properly look at a function's type
when determining if it returns.  Fixes <rdar://problem/7796563>.
llvm-svn: 99663
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Checker/NoReturnFunctionChecker.cpp | 82 | 
1 files changed, 41 insertions, 41 deletions
diff --git a/clang/lib/Checker/NoReturnFunctionChecker.cpp b/clang/lib/Checker/NoReturnFunctionChecker.cpp index 1455d87665d..80fea99c36c 100644 --- a/clang/lib/Checker/NoReturnFunctionChecker.cpp +++ b/clang/lib/Checker/NoReturnFunctionChecker.cpp @@ -13,17 +13,17 @@  //===----------------------------------------------------------------------===//  #include "GRExprEngineInternalChecks.h" -#include "clang/Checker/PathSensitive/Checker.h" +#include "clang/Checker/PathSensitive/CheckerVisitor.h"  #include "llvm/ADT/StringSwitch.h"  using namespace clang;  namespace { -class NoReturnFunctionChecker : public Checker { +class NoReturnFunctionChecker : public CheckerVisitor<NoReturnFunctionChecker> {  public:    static void *getTag() { static int tag = 0; return &tag; } -  virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE); +  void PostVisitCallExpr(CheckerContext &C, const CallExpr *CE);  };  } @@ -32,48 +32,48 @@ void clang::RegisterNoReturnFunctionChecker(GRExprEngine &Eng) {    Eng.registerCheck(new NoReturnFunctionChecker());  } -bool NoReturnFunctionChecker::EvalCallExpr(CheckerContext &C,  -                                           const CallExpr *CE) { +void NoReturnFunctionChecker::PostVisitCallExpr(CheckerContext &C, +                                                const CallExpr *CE) {    const GRState *state = C.getState();    const Expr *Callee = CE->getCallee(); -  SVal L = state->getSVal(Callee); -  const FunctionDecl *FD = L.getAsFunctionDecl(); -  if (!FD) -    return false; -  bool BuildSinks = false; +  bool BuildSinks = Callee->getType().getNoReturnAttr(); -  if (FD->getAttr<NoReturnAttr>() || FD->getAttr<AnalyzerNoReturnAttr>()) -    BuildSinks = true; -  else if (const IdentifierInfo *II = FD->getIdentifier()) { -    // HACK: Some functions are not marked noreturn, and don't return. -    //  Here are a few hardwired ones.  If this takes too long, we can -    //  potentially cache these results. -    BuildSinks  -      = llvm::StringSwitch<bool>(llvm::StringRef(II->getName())) -          .Case("exit", true) -          .Case("panic", true) -          .Case("error", true) -          .Case("Assert", true) -          // FIXME: This is just a wrapper around throwing an exception. -          //  Eventually inter-procedural analysis should handle this easily. -          .Case("ziperr", true) -          .Case("assfail", true) -          .Case("db_error", true) -          .Case("__assert", true) -          .Case("__assert_rtn", true) -          .Case("__assert_fail", true) -          .Case("dtrace_assfail", true) -          .Case("yy_fatal_error", true) -          .Case("_XCAssertionFailureHandler", true) -          .Case("_DTAssertionFailureHandler", true) -          .Case("_TSAssertionFailureHandler", true) -          .Default(false); +  if (!BuildSinks) { +    SVal L = state->getSVal(Callee); +    const FunctionDecl *FD = L.getAsFunctionDecl(); +    if (!FD) +      return; + +    if (FD->getAttr<AnalyzerNoReturnAttr>()) +      BuildSinks = true; +    else if (const IdentifierInfo *II = FD->getIdentifier()) { +      // HACK: Some functions are not marked noreturn, and don't return. +      //  Here are a few hardwired ones.  If this takes too long, we can +      //  potentially cache these results. +      BuildSinks +        = llvm::StringSwitch<bool>(llvm::StringRef(II->getName())) +            .Case("exit", true) +            .Case("panic", true) +            .Case("error", true) +            .Case("Assert", true) +            // FIXME: This is just a wrapper around throwing an exception. +            //  Eventually inter-procedural analysis should handle this easily. +            .Case("ziperr", true) +            .Case("assfail", true) +            .Case("db_error", true) +            .Case("__assert", true) +            .Case("__assert_rtn", true) +            .Case("__assert_fail", true) +            .Case("dtrace_assfail", true) +            .Case("yy_fatal_error", true) +            .Case("_XCAssertionFailureHandler", true) +            .Case("_DTAssertionFailureHandler", true) +            .Case("_TSAssertionFailureHandler", true) +            .Default(false); +    }    } -   -  if (!BuildSinks) -    return false; -  C.GenerateSink(CE); -  return true; +  if (BuildSinks) +    C.GenerateSink(CE);  }  | 

