diff options
author | Anna Zaks <ganna@apple.com> | 2011-12-01 05:57:37 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2011-12-01 05:57:37 +0000 |
commit | b805c8ff133ef0c62df032fa711d6b13c5afd7f4 (patch) | |
tree | 79e10913c825cdf113d9267320edc29decaaf4aa | |
parent | a078ecf3484d62b01d9f8c01e0fecffd65c583e1 (diff) |
[analyzer] Refactor checkers to use helper function for getting callee Decl and name.
We are getting name of the called function or it's declaration in a few checkers. Refactor them to use the helper function in the CheckerContext.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145576 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h | 3 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp | 10 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp | 7 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/CStringChecker.cpp | 15 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/ChrootChecker.cpp | 12 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp | 12 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp | 25 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 6 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp | 27 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp | 12 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp | 7 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/StreamChecker.cpp | 5 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp | 15 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/CheckerContext.cpp | 7 |
14 files changed, 52 insertions, 111 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h index 6f4bdd41fa..02c92c9150 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h @@ -142,6 +142,9 @@ public: Eng.getBugReporter().EmitReport(R); } + /// \brief Get the declaration of the called function (path-sensitive). + const FunctionDecl *getCalleeDecl(const CallExpr *CE) const; + /// \brief Get the name of the called function (path-sensitive). StringRef getCalleeName(const CallExpr *CE) const; diff --git a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp index bc6e8f303f..1f627297ec 100644 --- a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp +++ b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp @@ -249,11 +249,8 @@ static const char* GetCFNumberTypeStr(uint64_t i) { void CFNumberCreateChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const { - const Expr *Callee = CE->getCallee(); const ProgramState *state = C.getState(); - SVal CallV = state->getSVal(Callee); - const FunctionDecl *FD = CallV.getAsFunctionDecl(); - + const FunctionDecl *FD = C.getCalleeDecl(CE); if (!FD) return; @@ -363,11 +360,8 @@ void CFRetainReleaseChecker::checkPreStmt(const CallExpr *CE, if (CE->getNumArgs() != 1) return; - // Get the function declaration of the callee. const ProgramState *state = C.getState(); - SVal X = state->getSVal(CE->getCallee()); - const FunctionDecl *FD = X.getAsFunctionDecl(); - + const FunctionDecl *FD = C.getCalleeDecl(CE); if (!FD) return; diff --git a/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp b/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp index 4ad7cc9031..2cf1209f51 100644 --- a/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp @@ -30,12 +30,9 @@ public: } bool BuiltinFunctionChecker::evalCall(const CallExpr *CE, - CheckerContext &C) const{ + CheckerContext &C) const { const ProgramState *state = C.getState(); - const Expr *Callee = CE->getCallee(); - SVal L = state->getSVal(Callee); - const FunctionDecl *FD = L.getAsFunctionDecl(); - + const FunctionDecl *FD = C.getCalleeDecl(CE); if (!FD) return false; diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index 4299a12e38..6ab98b4187 100644 --- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -1664,20 +1664,9 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE, //===----------------------------------------------------------------------===// bool CStringChecker::evalCall(const CallExpr *CE, CheckerContext &C) const { - // Get the callee. All the functions we care about are C functions - // with simple identifiers. - const ProgramState *state = C.getState(); - const Expr *Callee = CE->getCallee(); - const FunctionDecl *FD = state->getSVal(Callee).getAsFunctionDecl(); - - if (!FD) - return false; - - // Get the name of the callee. If it's a builtin, strip off the prefix. - IdentifierInfo *II = FD->getIdentifier(); - if (!II) // if no identifier, not a simple C function + StringRef Name = C.getCalleeName(CE); + if (Name.empty()) return false; - StringRef Name = II->getName(); if (Name.startswith("__builtin_")) Name = Name.substr(10); diff --git a/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp b/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp index 2f3ff26de5..fa79f21866 100644 --- a/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp @@ -62,10 +62,7 @@ private: } // end anonymous namespace bool ChrootChecker::evalCall(const CallExpr *CE, CheckerContext &C) const { - const ProgramState *state = C.getState(); - const Expr *Callee = CE->getCallee(); - SVal L = state->getSVal(Callee); - const FunctionDecl *FD = L.getAsFunctionDecl(); + const FunctionDecl *FD = C.getCalleeDecl(CE); if (!FD) return false; @@ -125,10 +122,7 @@ void ChrootChecker::Chdir(CheckerContext &C, const CallExpr *CE) const { // Check the jail state before any function call except chroot and chdir(). void ChrootChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const { - const ProgramState *state = C.getState(); - const Expr *Callee = CE->getCallee(); - SVal L = state->getSVal(Callee); - const FunctionDecl *FD = L.getAsFunctionDecl(); + const FunctionDecl *FD = C.getCalleeDecl(CE); if (!FD) return; @@ -143,7 +137,7 @@ void ChrootChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const { return; // If jail state is ROOT_CHANGED, generate BugReport. - void *const* k = state->FindGDM(ChrootChecker::getTag()); + void *const* k = C.getState()->FindGDM(ChrootChecker::getTag()); if (k) if (isRootChanged((intptr_t) *k)) if (ExplodedNode *N = C.addTransition()) { diff --git a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp index c9de38c4a0..b49684233a 100644 --- a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp @@ -281,18 +281,12 @@ void MacOSKeychainAPIChecker:: void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const { - const ProgramState *State = C.getState(); - const Expr *Callee = CE->getCallee(); - SVal L = State->getSVal(Callee); unsigned idx = InvalidIdx; + const ProgramState *State = C.getState(); - const FunctionDecl *funDecl = L.getAsFunctionDecl(); - if (!funDecl) - return; - IdentifierInfo *funI = funDecl->getIdentifier(); - if (!funI) + StringRef funName = C.getCalleeName(CE); + if (funName.empty()) return; - StringRef funName = funI->getName(); // If it is a call to an allocator function, it could be a double allocation. idx = getTrackedFunctionIndex(funName, true); diff --git a/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp index 88d492e8d9..f8c01047c3 100644 --- a/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp @@ -37,11 +37,11 @@ public: void checkPreStmt(const CallExpr *CE, CheckerContext &C) const; void CheckDispatchOnce(CheckerContext &C, const CallExpr *CE, - const IdentifierInfo *FI) const; + StringRef FName) const; typedef void (MacOSXAPIChecker::*SubChecker)(CheckerContext &, const CallExpr *, - const IdentifierInfo *) const; + StringRef FName) const; }; } //end anonymous namespace @@ -50,7 +50,7 @@ public: //===----------------------------------------------------------------------===// void MacOSXAPIChecker::CheckDispatchOnce(CheckerContext &C, const CallExpr *CE, - const IdentifierInfo *FI) const { + StringRef FName) const { if (CE->getNumArgs() < 1) return; @@ -71,7 +71,7 @@ void MacOSXAPIChecker::CheckDispatchOnce(CheckerContext &C, const CallExpr *CE, llvm::SmallString<256> S; llvm::raw_svector_ostream os(S); - os << "Call to '" << FI->getName() << "' uses"; + os << "Call to '" << FName << "' uses"; if (const VarRegion *VR = dyn_cast<VarRegion>(R)) os << " the local variable '" << VR->getDecl()->getName() << '\''; else @@ -92,27 +92,18 @@ void MacOSXAPIChecker::CheckDispatchOnce(CheckerContext &C, const CallExpr *CE, void MacOSXAPIChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const { - // FIXME: This sort of logic is common to several checkers, including - // UnixAPIChecker, PthreadLockChecker, and CStringChecker. Should refactor. - const ProgramState *state = C.getState(); - const Expr *Callee = CE->getCallee(); - const FunctionDecl *Fn = state->getSVal(Callee).getAsFunctionDecl(); - - if (!Fn) - return; - - const IdentifierInfo *FI = Fn->getIdentifier(); - if (!FI) + StringRef Name = C.getCalleeName(CE); + if (Name.empty()) return; SubChecker SC = - llvm::StringSwitch<SubChecker>(FI->getName()) + llvm::StringSwitch<SubChecker>(Name) .Cases("dispatch_once", "dispatch_once_f", &MacOSXAPIChecker::CheckDispatchOnce) .Default(NULL); if (SC) - (this->*SC)(C, CE, FI); + (this->*SC)(C, CE, Name); } //===----------------------------------------------------------------------===// diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index f217df9309..dd919e3a9b 100644 --- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -128,11 +128,7 @@ namespace ento { } bool MallocChecker::evalCall(const CallExpr *CE, CheckerContext &C) const { - const ProgramState *state = C.getState(); - const Expr *Callee = CE->getCallee(); - SVal L = state->getSVal(Callee); - - const FunctionDecl *FD = L.getAsFunctionDecl(); + const FunctionDecl *FD = C.getCalleeDecl(CE); if (!FD) return false; diff --git a/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp b/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp index 7bdb871db9..27d8fb5abb 100644 --- a/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp @@ -35,23 +35,26 @@ private: }; } +static StringRef getCalleeName(const ProgramState *State, + const CallExpr *CE) { + const Expr *Callee = CE->getCallee(); + SVal L = State->getSVal(Callee); + const FunctionDecl *funDecl = L.getAsFunctionDecl(); + if (!funDecl) + return StringRef(); + IdentifierInfo *funI = funDecl->getIdentifier(); + if (!funI) + return StringRef(); + return funI->getName(); +} + bool OSAtomicChecker::inlineCall(const CallExpr *CE, ExprEngine &Eng, ExplodedNode *Pred, ExplodedNodeSet &Dst) const { - const ProgramState *state = Pred->getState(); - const Expr *Callee = CE->getCallee(); - SVal L = state->getSVal(Callee); - - const FunctionDecl *FD = L.getAsFunctionDecl(); - if (!FD) - return false; - - const IdentifierInfo *II = FD->getIdentifier(); - if (!II) + StringRef FName = getCalleeName(Pred->getState(), CE); + if (FName.empty()) return false; - - StringRef FName(II->getName()); // Check for compare and swap. if (FName.startswith("OSAtomicCompareAndSwap") || diff --git a/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp b/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp index c02b5b14ca..45988f0a09 100644 --- a/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp @@ -57,17 +57,9 @@ template <> struct ProgramStateTrait<LockSet> : void PthreadLockChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const { const ProgramState *state = C.getState(); - const Expr *Callee = CE->getCallee(); - const FunctionDecl *FD = state->getSVal(Callee).getAsFunctionDecl(); - - if (!FD) - return; - - // Get the name of the callee. - IdentifierInfo *II = FD->getIdentifier(); - if (!II) // if no identifier, not a simple C function + StringRef FName = C.getCalleeName(CE); + if (FName.empty()) return; - StringRef FName = II->getName(); if (CE->getNumArgs() != 1) return; diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp index 9537b31290..22cd050df3 100644 --- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp @@ -2990,10 +2990,7 @@ void RetainCountChecker::processNonLeakError(const ProgramState *St, bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const { // Get the callee. We're only interested in simple C functions. const ProgramState *state = C.getState(); - const Expr *Callee = CE->getCallee(); - SVal L = state->getSVal(Callee); - - const FunctionDecl *FD = L.getAsFunctionDecl(); + const FunctionDecl *FD = C.getCalleeDecl(CE); if (!FD) return false; @@ -3015,7 +3012,7 @@ bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const { // See if it's one of the specific functions we know how to eval. bool canEval = false; - QualType ResultTy = FD->getResultType(); + QualType ResultTy = CE->getCallReturnType(); if (ResultTy->isObjCIdType()) { // Handle: id NSMakeCollectable(CFTypeRef) canEval = II->isStr("NSMakeCollectable"); diff --git a/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/lib/StaticAnalyzer/Checkers/StreamChecker.cpp index 94ff2663aa..2f96bbfeac 100644 --- a/lib/StaticAnalyzer/Checkers/StreamChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/StreamChecker.cpp @@ -115,10 +115,7 @@ namespace ento { } bool StreamChecker::evalCall(const CallExpr *CE, CheckerContext &C) const { - const ProgramState *state = C.getState(); - const Expr *Callee = CE->getCallee(); - SVal L = state->getSVal(Callee); - const FunctionDecl *FD = L.getAsFunctionDecl(); + const FunctionDecl *FD = C.getCalleeDecl(CE); if (!FD) return false; diff --git a/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp index cec286d2f3..e955f9e90c 100644 --- a/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp @@ -224,21 +224,12 @@ void UnixAPIChecker::CheckMallocZero(CheckerContext &C, //===----------------------------------------------------------------------===// void UnixAPIChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const { - // Get the callee. All the functions we care about are C functions - // with simple identifiers. - const ProgramState *state = C.getState(); - const Expr *Callee = CE->getCallee(); - const FunctionDecl *Fn = state->getSVal(Callee).getAsFunctionDecl(); - - if (!Fn) - return; - - const IdentifierInfo *FI = Fn->getIdentifier(); - if (!FI) + StringRef FName = C.getCalleeName(CE); + if (FName.empty()) return; SubChecker SC = - llvm::StringSwitch<SubChecker>(FI->getName()) + llvm::StringSwitch<SubChecker>(FName) .Case("open", &UnixAPIChecker::CheckOpen) .Case("pthread_once", &UnixAPIChecker::CheckPthreadOnce) .Case("malloc", &UnixAPIChecker::CheckMallocZero) diff --git a/lib/StaticAnalyzer/Core/CheckerContext.cpp b/lib/StaticAnalyzer/Core/CheckerContext.cpp index 75cb82a67c..5552a991d1 100644 --- a/lib/StaticAnalyzer/Core/CheckerContext.cpp +++ b/lib/StaticAnalyzer/Core/CheckerContext.cpp @@ -16,12 +16,15 @@ using namespace clang; using namespace ento; -StringRef CheckerContext::getCalleeName(const CallExpr *CE) const { +const FunctionDecl *CheckerContext::getCalleeDecl(const CallExpr *CE) const { const ProgramState *State = getState(); const Expr *Callee = CE->getCallee(); SVal L = State->getSVal(Callee); + return L.getAsFunctionDecl(); +} - const FunctionDecl *funDecl = L.getAsFunctionDecl(); +StringRef CheckerContext::getCalleeName(const CallExpr *CE) const { + const FunctionDecl *funDecl = getCalleeDecl(CE); if (!funDecl) return StringRef(); IdentifierInfo *funI = funDecl->getIdentifier(); |