diff options
Diffstat (limited to 'lib/Analysis')
-rw-r--r-- | lib/Analysis/BasicObjCFoundationChecks.cpp | 4 | ||||
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 20 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 21 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngineInternalChecks.cpp | 8 | ||||
-rw-r--r-- | lib/Analysis/SVals.cpp | 23 |
5 files changed, 44 insertions, 32 deletions
diff --git a/lib/Analysis/BasicObjCFoundationChecks.cpp b/lib/Analysis/BasicObjCFoundationChecks.cpp index 88f480e68c..0eee9374da 100644 --- a/lib/Analysis/BasicObjCFoundationChecks.cpp +++ b/lib/Analysis/BasicObjCFoundationChecks.cpp @@ -375,9 +375,9 @@ bool AuditCFNumberCreate::Audit(ExplodedNode<GRState>* N,GRStateManager&){ CallExpr* CE = cast<CallExpr>(cast<PostStmt>(N->getLocation()).getStmt()); Expr* Callee = CE->getCallee(); SVal CallV = GetSVal(N->getState(), Callee); - loc::FuncVal* FuncV = dyn_cast<loc::FuncVal>(&CallV); + const FunctionDecl* FD = CallV.getAsFunctionDecl(); - if (!FuncV || FuncV->getDecl()->getIdentifier() != II || CE->getNumArgs()!=3) + if (!FD || FD->getIdentifier() != II || CE->getNumArgs()!=3) return false; // Get the value of the "theType" argument. diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 7443c521b3..0e8d67ca29 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -1694,7 +1694,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst, Expr* Ex, Expr* Receiver, RetainSummary* Summ, - ExprIterator arg_beg, ExprIterator arg_end, + ExprIterator arg_beg, ExprIterator arg_end, ExplodedNode<GRState>* Pred) { // Get the state. @@ -1930,9 +1930,9 @@ void CFRefCount::EvalCall(ExplodedNodeSet<GRState>& Dst, GRStmtNodeBuilder<GRState>& Builder, CallExpr* CE, SVal L, ExplodedNode<GRState>* Pred) { - - RetainSummary* Summ = !isa<loc::FuncVal>(L) ? 0 - : Summaries.getSummary(cast<loc::FuncVal>(L).getDecl()); + const FunctionDecl* FD = L.getAsFunctionDecl(); + RetainSummary* Summ = !FD ? 0 + : Summaries.getSummary(const_cast<FunctionDecl*>(FD)); EvalSummary(Dst, Eng, Builder, CE, 0, Summ, CE->arg_begin(), CE->arg_end(), Pred); @@ -2582,9 +2582,9 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode<GRState>* N, if (CallExpr *CE = dyn_cast<CallExpr>(S)) { // Get the name of the callee (if it is available). - SVal X = CurrSt.GetSValAsScalarOrLoc(CE->getCallee()); - if (loc::FuncVal* FV = dyn_cast<loc::FuncVal>(&X)) - os << "Call to function '" << FV->getDecl()->getNameAsString() <<'\''; + SVal X = CurrSt.GetSValAsScalarOrLoc(CE->getCallee()); + if (const FunctionDecl* FD = X.getAsFunctionDecl()) + os << "Call to function '" << FD->getNameAsString() <<'\''; else os << "function call"; } @@ -2675,9 +2675,9 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode<GRState>* N, if (contains(AEffects, MakeCollectable)) { // Get the name of the function. Stmt* S = cast<PostStmt>(N->getLocation()).getStmt(); - loc::FuncVal FV = - cast<loc::FuncVal>(CurrSt.GetSValAsScalarOrLoc(cast<CallExpr>(S)->getCallee())); - const std::string& FName = FV.getDecl()->getNameAsString(); + SVal X = CurrSt.GetSValAsScalarOrLoc(cast<CallExpr>(S)->getCallee()); + const FunctionDecl* FD = X.getAsFunctionDecl(); + const std::string& FName = FD->getNameAsString(); if (TF.isGCEnabled()) { // Determine if the object's reference count was pushed to zero. diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 43d7331dd9..d00bfe640a 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -976,7 +976,7 @@ void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* Ex, NodeTy* Pred, NodeSet& Dst, } else if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(D)) { assert(asLValue); - SVal V = loc::FuncVal(FD); + SVal V = ValMgr.getFunctionPointer(FD); MakeNode(Dst, Ex, Pred, BindExpr(state, Ex, V)); return; } @@ -1369,11 +1369,10 @@ static bool EvalOSAtomic(ExplodedNodeSet<GRState>& Dst, GRStmtNodeBuilder<GRState>& Builder, CallExpr* CE, SVal L, ExplodedNode<GRState>* Pred) { - - if (!isa<loc::FuncVal>(L)) + const FunctionDecl* FD = L.getAsFunctionDecl(); + if (!FD) return false; - - const FunctionDecl *FD = cast<loc::FuncVal>(L).getDecl(); + const char *FName = FD->getNameAsCString(); // Check for compare and swap. @@ -1473,11 +1472,8 @@ void GRExprEngine::VisitCallRec(CallExpr* CE, NodeTy* Pred, // Check for the "noreturn" attribute. SaveAndRestore<bool> OldSink(Builder->BuildSinks); - - if (isa<loc::FuncVal>(L)) { - - FunctionDecl* FD = cast<loc::FuncVal>(L).getDecl(); - + const FunctionDecl* FD = L.getAsFunctionDecl(); + if (FD) { if (FD->getAttr<NoReturnAttr>() || FD->getAttr<AnalyzerNoReturnAttr>()) Builder->BuildSinks = true; else { @@ -1559,10 +1555,9 @@ void GRExprEngine::VisitCallRec(CallExpr* CE, NodeTy* Pred, // Evaluate the call. - if (isa<loc::FuncVal>(L)) { + if (FD) { - if (unsigned id - = cast<loc::FuncVal>(L).getDecl()->getBuiltinID(getContext())) + if (unsigned id = FD->getBuiltinID(getContext())) switch (id) { case Builtin::BI__builtin_expect: { // For __builtin_expect, just return the value of the subexpression. diff --git a/lib/Analysis/GRExprEngineInternalChecks.cpp b/lib/Analysis/GRExprEngineInternalChecks.cpp index f4efdb1250..1b03149204 100644 --- a/lib/Analysis/GRExprEngineInternalChecks.cpp +++ b/lib/Analysis/GRExprEngineInternalChecks.cpp @@ -432,11 +432,11 @@ public: const GRState* state = N->getState(); SVal X = VMgr.GetSVal(state, CE->getCallee()); - - if (!isa<loc::FuncVal>(X)) + + const FunctionDecl* FD = X.getAsFunctionDecl(); + if (!FD) return false; - - FunctionDecl* FD = dyn_cast<FunctionDecl>(cast<loc::FuncVal>(X).getDecl()); + const NonNullAttr* Att = FD->getAttr<NonNullAttr>(); if (!Att) diff --git a/lib/Analysis/SVals.cpp b/lib/Analysis/SVals.cpp index 240280f68a..875fd36747 100644 --- a/lib/Analysis/SVals.cpp +++ b/lib/Analysis/SVals.cpp @@ -30,9 +30,25 @@ using llvm::APSInt; // Utility methods. //===----------------------------------------------------------------------===// +const FunctionDecl* SVal::getAsFunctionDecl() const { + if (const loc::FuncVal* FV = dyn_cast<loc::FuncVal>(this)) { + return FV->getDecl(); + } + + if (const loc::MemRegionVal* X = dyn_cast<loc::MemRegionVal>(this)) { + const MemRegion* R = X->getRegion(); + if (const CodeTextRegion* CTR = dyn_cast<CodeTextRegion>(R)) { + if (CTR->isDeclared()) + return CTR->getDecl(); + } + } + + return 0; +} + /// getAsLocSymbol - If this SVal is a location (subclasses Loc) and -/// wraps a symbol, return that SymbolRef. Otherwise return a SymbolRef -/// where 'isValid()' returns false. +/// wraps a symbol, return that SymbolRef. Otherwise return 0. +// FIXME: should we consider SymbolRef wrapped in CodeTextRegion? SymbolRef SVal::getAsLocSymbol() const { if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this)) { const MemRegion *R = X->getRegion(); @@ -55,7 +71,8 @@ SymbolRef SVal::getAsLocSymbol() const { } /// getAsSymbol - If this Sval wraps a symbol return that SymbolRef. -/// Otherwise return a SymbolRef where 'isValid()' returns false. +/// Otherwise return 0. +// FIXME: should we consider SymbolRef wrapped in CodeTextRegion? SymbolRef SVal::getAsSymbol() const { if (const nonloc::SymbolVal *X = dyn_cast<nonloc::SymbolVal>(this)) return X->getSymbol(); |