From 97ed4f68f5dba3e21e7a490ef0f9ffd3bfead7f8 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 17 Oct 2008 00:03:18 +0000 Subject: [PATCH] Add transfer function support for ObjCIvarRefExpr. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57654 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Analysis/PathSensitive/GRExprEngine.h | 6 ++++ .../clang/Analysis/PathSensitive/GRState.h | 6 ++++ include/clang/Analysis/PathSensitive/Store.h | 6 ++++ lib/Analysis/BasicStore.cpp | 6 ++++ lib/Analysis/GRExprEngine.cpp | 35 +++++++++++++++++-- 5 files changed, 57 insertions(+), 2 deletions(-) diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 8a4f9cd6c9..d1e25a5a66 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -441,6 +441,8 @@ protected: } // Get the lvalue of an expression. + // FIXME: Remove this method, and used specialized versions of GetLValue + // in GRStateManager. RVal GetLValue(const GRState* St, const Expr* Ex) { return StateMgr.GetLValue(St, Ex); } @@ -521,6 +523,10 @@ protected: /// VisitMemberExpr - Transfer function for member expressions. void VisitMemberExpr(MemberExpr* M, NodeTy* Pred, NodeSet& Dst,bool asLValue); + /// VisitObjCIvarRefExpr - Transfer function logic for ObjCIvarRefExprs. + void VisitObjCIvarRefExpr(ObjCIvarRefExpr* DR, NodeTy* Pred, NodeSet& Dst, + bool asLValue); + /// VisitObjCMessageExpr - Transfer function for ObjC message expressions. void VisitObjCMessageExpr(ObjCMessageExpr* ME, NodeTy* Pred, NodeSet& Dst); diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h index 130160c4ed..2ae671cec3 100644 --- a/include/clang/Analysis/PathSensitive/GRState.h +++ b/include/clang/Analysis/PathSensitive/GRState.h @@ -346,11 +346,17 @@ public: } // Get the lvalue of expression. + // FIXME: Remove this method, and implement specialized versions for + // specific Decls. RVal GetLValue(const GRState* St, const Expr* Ex) { // Forward to store manager. The lvalue of an expression is determined by // the store manager. return StoreMgr->getLValue(St, Ex); } + + RVal GetLValue(const GRState* St, ObjCIvarDecl* D, RVal Base) { + return StoreMgr->getLValue(St, D, Base); + } // Methods that query & manipulate the Environment. diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index b6c9c5d302..c61b482098 100644 --- a/include/clang/Analysis/PathSensitive/Store.h +++ b/include/clang/Analysis/PathSensitive/Store.h @@ -30,6 +30,7 @@ class GRStateManager; class LiveVariables; class Stmt; class Expr; +class ObjCIvarDecl; class MemRegion; class MemRegionManager; @@ -47,7 +48,12 @@ public: virtual LVal getLVal(const VarDecl* VD) = 0; // Get the lvalue of an expression. + // FIXME: Remove this method, and implement specialized versions for + // specific Decls. virtual RVal getLValue(const GRState* St, const Expr* Ex) = 0; + + virtual RVal getLValue(const GRState* St, const ObjCIvarDecl* D, RVal Base)=0; + virtual Store RemoveDeadBindings(Store store, Stmt* Loc, const LiveVariables& Live, diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp index f97f8b2c29..15a20c843a 100644 --- a/lib/Analysis/BasicStore.cpp +++ b/lib/Analysis/BasicStore.cpp @@ -48,6 +48,7 @@ public: } virtual RVal getLValue(const GRState* St, const Expr* Ex); + virtual RVal getLValue(const GRState* St, const ObjCIvarDecl* D, RVal Base); virtual Store RemoveDeadBindings(Store store, Stmt* Loc, const LiveVariables& Live, @@ -154,6 +155,11 @@ RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) { return UnknownVal(); } +RVal BasicStoreManager::getLValue(const GRState* St, const ObjCIvarDecl* D, + RVal Base) { + return UnknownVal(); +} + Store BasicStoreManager::SetRVal(Store store, LVal LV, RVal V) { switch (LV.getSubKind()) { case lval::MemRegionKind: { diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 2d241344af..f974dfc2c4 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -350,10 +350,13 @@ void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) { break; } - case Stmt::MemberExprClass: { + case Stmt::MemberExprClass: VisitMemberExpr(cast(S), Pred, Dst, false); break; - } + + case Stmt::ObjCIvarRefExprClass: + VisitObjCIvarRefExpr(cast(S), Pred, Dst, false); + break; case Stmt::ObjCMessageExprClass: { VisitObjCMessageExpr(cast(S), Pred, Dst); @@ -417,6 +420,10 @@ void GRExprEngine::VisitLValue(Expr* Ex, NodeTy* Pred, NodeSet& Dst) { VisitDeclRefExpr(cast(Ex), Pred, Dst, true); return; + case Stmt::ObjCIvarRefExprClass: + VisitObjCIvarRefExpr(cast(Ex), Pred, Dst, true); + return; + case Stmt::UnaryOperatorClass: VisitUnaryOperator(cast(Ex), Pred, Dst, true); return; @@ -1222,6 +1229,30 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred, } } +//===----------------------------------------------------------------------===// +// Transfer function: Objective-C ivar references. +//===----------------------------------------------------------------------===// + +void GRExprEngine::VisitObjCIvarRefExpr(ObjCIvarRefExpr* Ex, + NodeTy* Pred, NodeSet& Dst, + bool asLValue) { + + Expr* Base = cast(Ex->getBase()); + NodeSet Tmp; + Visit(Base, Pred, Tmp); + + for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { + const GRState* St = GetState(*I); + RVal BaseVal = GetRVal(St, Base); + RVal location = StateMgr.GetLValue(St, Ex->getDecl(), BaseVal); + + if (asLValue) + MakeNode(Dst, Ex, *I, SetRVal(St, Ex, location)); + else + EvalLoad(Dst, Ex, *I, St, location); + } +} + //===----------------------------------------------------------------------===// // Transfer function: Objective-C message expressions. //===----------------------------------------------------------------------===// -- 2.40.0