[cfe-commits] r91535 - in /cfe/trunk: include/clang/Analysis/PathSensitive/GRExprEngine.h include/clang/Analysis/PathSensitive/MemRegion.h include/clang/Analysis/PathSensitive/Store.h lib/Analysis/GRExprEngine.cpp lib/Analysis/MemRegion.cpp lib/Analysis/RegionStore.cpp lib/Analysis/Store.cpp
Ted Kremenek
kremenek at apple.com
Wed Dec 16 11:12:11 PST 2009
Hi Zhongxing,
How do we plan on using CXXObjectRegion?
For stack allocated objects, we will use VarRegions. For heap allocated (e.g., 'new'), we will use SymbolicRegions. For fields that are C++ objects we will use FieldRegions.
It seems that the only place where we would use CXXObjectRegions are for modeling the object associated with analyzing a specific method, but I'm not sure that is necessary or the right approach. ObjCObjectRegion is currently only used by BasicStoreManager, and that should probably be fixed so it can be removed. RegionStoreManager handles the Objective-C 'self' variable by using a VarRegion for the 'self' ImplicitParamDecl, and then represents the actual Objective-C object with a SymbolicRegion. There is no ImplicitParamDecl for 'this', but conceptually that's what we want: a way to go from CXXThisExpr to the region that represents the current object. That way when we inline method calls we can simply map from ("this",LocationContext) -> MemRegion*.
Ted
On Dec 16, 2009, at 3:27 AM, Zhongxing Xu wrote:
> Author: zhongxingxu
> Date: Wed Dec 16 05:27:52 2009
> New Revision: 91535
>
> URL: http://llvm.org/viewvc/llvm-project?rev=91535&view=rev
> Log:
> Add a new kind of region: CXXObjectRegion. Currently it has only one
> attribute: the object type.
> Add initial support for visiting CXXThisExpr.
> Fix a bunch of 80-col violations.
>
> Modified:
> cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
> cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h
> cfe/trunk/include/clang/Analysis/PathSensitive/Store.h
> cfe/trunk/lib/Analysis/GRExprEngine.cpp
> cfe/trunk/lib/Analysis/MemRegion.cpp
> cfe/trunk/lib/Analysis/RegionStore.cpp
> cfe/trunk/lib/Analysis/Store.cpp
>
> Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=91535&r1=91534&r2=91535&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
> +++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Wed Dec 16 05:27:52 2009
> @@ -25,6 +25,7 @@
> #include "clang/Analysis/PathSensitive/BugReporter.h"
> #include "clang/AST/Type.h"
> #include "clang/AST/ExprObjC.h"
> +#include "clang/AST/ExprCXX.h"
>
> namespace clang {
>
> @@ -203,9 +204,10 @@
> }
>
> public:
> - ExplodedNode* MakeNode(ExplodedNodeSet& Dst, Stmt* S, ExplodedNode* Pred, const GRState* St,
> - ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
> - const void *tag = 0);
> + ExplodedNode* MakeNode(ExplodedNodeSet& Dst, Stmt* S, ExplodedNode* Pred,
> + const GRState* St,
> + ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
> + const void *tag = 0);
> protected:
> /// CheckerVisit - Dispatcher for performing checker-specific logic
> /// at specific statements.
> @@ -315,18 +317,21 @@
> void VisitObjCForCollectionStmt(ObjCForCollectionStmt* S, ExplodedNode* Pred,
> ExplodedNodeSet& Dst);
>
> - void VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S, ExplodedNode* Pred,
> + void VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S,
> + ExplodedNode* Pred,
> ExplodedNodeSet& Dst, SVal ElementV);
>
> /// VisitObjCMessageExpr - Transfer function for ObjC message expressions.
> - void VisitObjCMessageExpr(ObjCMessageExpr* ME, ExplodedNode* Pred, ExplodedNodeSet& Dst);
> + void VisitObjCMessageExpr(ObjCMessageExpr* ME, ExplodedNode* Pred,
> + ExplodedNodeSet& Dst);
>
> void VisitObjCMessageExprArgHelper(ObjCMessageExpr* ME,
> ObjCMessageExpr::arg_iterator I,
> ObjCMessageExpr::arg_iterator E,
> ExplodedNode* Pred, ExplodedNodeSet& Dst);
>
> - void VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME, ExplodedNode* Pred,
> + void VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME,
> + ExplodedNode* Pred,
> ExplodedNodeSet& Dst);
>
> /// VisitReturnStmt - Transfer function logic for return statements.
> @@ -337,8 +342,11 @@
> ExplodedNodeSet& Dst);
>
> /// VisitUnaryOperator - Transfer function logic for unary operators.
> - void VisitUnaryOperator(UnaryOperator* B, ExplodedNode* Pred, ExplodedNodeSet& Dst,
> - bool asLValue);
> + void VisitUnaryOperator(UnaryOperator* B, ExplodedNode* Pred,
> + ExplodedNodeSet& Dst, bool asLValue);
> +
> + void VisitCXXThisExpr(CXXThisExpr *TE, ExplodedNode *Pred,
> + ExplodedNodeSet & Dst);
>
> /// EvalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic
> /// expressions of the form 'x != 0' and generate new nodes (stored in Dst)
> @@ -362,7 +370,7 @@
>
> SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op,
> NonLoc L, SVal R, QualType T) {
> - return R.isValid() ? SVator.EvalBinOpNN(state, op, L, cast<NonLoc>(R), T) : R;
> + return R.isValid() ? SVator.EvalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R;
> }
>
> SVal EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
>
> Modified: cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h?rev=91535&r1=91534&r2=91535&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h (original)
> +++ cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h Wed Dec 16 05:27:52 2009
> @@ -73,7 +73,8 @@
> FieldRegionKind,
> ObjCIvarRegionKind,
> ObjCObjectRegionKind,
> - END_DECL_REGIONS = ObjCObjectRegionKind,
> + CXXObjectRegionKind,
> + END_DECL_REGIONS = CXXObjectRegionKind,
> END_TYPED_REGIONS = END_DECL_REGIONS
> };
>
> @@ -752,6 +753,30 @@
> }
> };
>
> +class CXXObjectRegion : public TypedRegion {
> + friend class MemRegionManager;
> +
> + // T - The object type.
> + QualType T;
> +
> + CXXObjectRegion(QualType t, const MemRegion *sReg)
> + : TypedRegion(sReg, CXXObjectRegionKind), T(t) {}
> +
> + static void ProfileRegion(llvm::FoldingSetNodeID &ID,
> + QualType T, const MemRegion *sReg);
> +
> +public:
> + QualType getValueType(ASTContext& C) const {
> + return T;
> + }
> +
> + void Profile(llvm::FoldingSetNodeID &ID) const;
> +
> + static bool classof(const MemRegion* R) {
> + return R->getKind() == CXXObjectRegionKind;
> + }
> +};
> +
> template<typename RegionTy>
> const RegionTy* MemRegion::getAs() const {
> if (const RegionTy* RT = dyn_cast<RegionTy>(this))
> @@ -877,6 +902,8 @@
> const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl* ivd,
> const MemRegion* superRegion);
>
> + const CXXObjectRegion *getCXXObjectRegion(QualType T);
> +
> const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
> const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,
> CanQualType locTy,
>
> Modified: cfe/trunk/include/clang/Analysis/PathSensitive/Store.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/Store.h?rev=91535&r1=91534&r2=91535&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Analysis/PathSensitive/Store.h (original)
> +++ cfe/trunk/include/clang/Analysis/PathSensitive/Store.h Wed Dec 16 05:27:52 2009
> @@ -103,6 +103,9 @@
>
> virtual SVal getLValueElement(QualType elementType, SVal offset, SVal Base)=0;
>
> + // T - the object type.
> + Loc getThisObject(QualType T);
> +
> // FIXME: Make out-of-line.
> virtual DefinedOrUnknownSVal getSizeInElements(const GRState *state,
> const MemRegion *region) {
>
> Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=91535&r1=91534&r2=91535&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
> +++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Wed Dec 16 05:27:52 2009
> @@ -506,7 +506,6 @@
> case Stmt::CXXTypeidExprClass:
> case Stmt::CXXBoolLiteralExprClass:
> case Stmt::CXXNullPtrLiteralExprClass:
> - case Stmt::CXXThisExprClass:
> case Stmt::CXXThrowExprClass:
> case Stmt::CXXDefaultArgExprClass:
> case Stmt::CXXZeroInitValueExprClass:
> @@ -567,7 +566,8 @@
> break;
> }
>
> - if (AMgr.shouldEagerlyAssume() && (B->isRelationalOp() || B->isEqualityOp())) {
> + if (AMgr.shouldEagerlyAssume() &&
> + (B->isRelationalOp() || B->isEqualityOp())) {
> ExplodedNodeSet Tmp;
> VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp, false);
> EvalEagerlyAssume(Dst, Tmp, cast<Expr>(S));
> @@ -608,6 +608,10 @@
> break;
> }
>
> + case Stmt::CXXThisExprClass:
> + VisitCXXThisExpr(cast<CXXThisExpr>(S), Pred, Dst);
> + break;
> +
> case Stmt::DeclRefExprClass:
> VisitDeclRefExpr(cast<DeclRefExpr>(S), Pred, Dst, false);
> break;
> @@ -692,7 +696,7 @@
>
> case Stmt::UnaryOperatorClass: {
> UnaryOperator *U = cast<UnaryOperator>(S);
> - if (AMgr.shouldEagerlyAssume() && (U->getOpcode() == UnaryOperator::LNot)) {
> + if (AMgr.shouldEagerlyAssume()&&(U->getOpcode() == UnaryOperator::LNot)) {
> ExplodedNodeSet Tmp;
> VisitUnaryOperator(U, Pred, Tmp, false);
> EvalEagerlyAssume(Dst, Tmp, U);
> @@ -709,7 +713,7 @@
>
> Ex = Ex->IgnoreParens();
>
> - if (Ex != CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(Ex)) {
> + if (Ex != CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(Ex)){
> Dst.Add(Pred);
> return;
> }
> @@ -1025,7 +1029,8 @@
> void GRExprEngine::VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R,
> ExplodedNode* Pred, ExplodedNodeSet& Dst) {
>
> - assert (Ex == CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(Ex));
> + assert(Ex == CurrentStmt &&
> + Pred->getLocationContext()->getCFG()->isBlkExpr(Ex));
>
> const GRState* state = GetState(Pred);
> SVal X = state->getSVal(Ex);
> @@ -1149,7 +1154,7 @@
> assert(B->getOpcode() == BinaryOperator::LAnd ||
> B->getOpcode() == BinaryOperator::LOr);
>
> - assert(B == CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(B));
> + assert(B==CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(B));
>
> const GRState* state = GetState(Pred);
> SVal X = state->getSVal(B);
> @@ -2067,7 +2072,7 @@
> }
>
> EvalBind(Dst, DS, DS, *I, state,
> - loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true);
> + loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true);
> }
> else {
> state = state->bindDeclWithNoInit(state->getRegion(VD, LC));
> @@ -2129,7 +2134,7 @@
>
> InitListExpr::reverse_iterator NewItr = X.Itr + 1;
>
> - for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) {
> + for (ExplodedNodeSet::iterator NI=Tmp.begin(),NE=Tmp.end();NI!=NE;++NI) {
> // Get the last initializer value.
> state = GetState(*NI);
> SVal InitV = state->getSVal(cast<Expr>(*X.Itr));
> @@ -2161,7 +2166,7 @@
> ExplodedNodeSet Tmp;
> Expr* Init = E->getInit(0);
> Visit(Init, Pred, Tmp);
> - for (ExplodedNodeSet::iterator I = Tmp.begin(), EI = Tmp.end(); I != EI; ++I) {
> + for (ExplodedNodeSet::iterator I=Tmp.begin(), EI=Tmp.end(); I != EI; ++I) {
> state = GetState(*I);
> MakeNode(Dst, E, *I, state->BindExpr(E, state->getSVal(Init)));
> }
> @@ -2429,7 +2434,7 @@
> ExplodedNodeSet Tmp2;
> EvalLoad(Tmp2, Ex, *I, state, V1);
>
> - for (ExplodedNodeSet::iterator I2 = Tmp2.begin(), E2 = Tmp2.end(); I2!=E2; ++I2) {
> + for (ExplodedNodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end();I2!=E2;++I2) {
>
> state = GetState(*I2);
> SVal V2_untested = state->getSVal(Ex);
> @@ -2492,14 +2497,23 @@
> }
> }
>
> -void GRExprEngine::VisitAsmStmt(AsmStmt* A, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
> +
> +void GRExprEngine::VisitCXXThisExpr(CXXThisExpr *TE, ExplodedNode *Pred,
> + ExplodedNodeSet & Dst) {
> + // Get the this object region from StoreManager.
> + Loc V = getStoreManager().getThisObject(TE->getType()->getPointeeType());
> + MakeNode(Dst, TE, Pred, GetState(Pred)->BindExpr(TE, V));
> +}
> +
> +void GRExprEngine::VisitAsmStmt(AsmStmt* A, ExplodedNode* Pred,
> + ExplodedNodeSet& Dst) {
> VisitAsmStmtHelperOutputs(A, A->begin_outputs(), A->end_outputs(), Pred, Dst);
> }
>
> void GRExprEngine::VisitAsmStmtHelperOutputs(AsmStmt* A,
> AsmStmt::outputs_iterator I,
> AsmStmt::outputs_iterator E,
> - ExplodedNode* Pred, ExplodedNodeSet& Dst) {
> + ExplodedNode* Pred, ExplodedNodeSet& Dst) {
> if (I == E) {
> VisitAsmStmtHelperInputs(A, A->begin_inputs(), A->end_inputs(), Pred, Dst);
> return;
> @@ -2510,14 +2524,15 @@
>
> ++I;
>
> - for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI)
> + for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end();NI != NE;++NI)
> VisitAsmStmtHelperOutputs(A, I, E, *NI, Dst);
> }
>
> void GRExprEngine::VisitAsmStmtHelperInputs(AsmStmt* A,
> AsmStmt::inputs_iterator I,
> AsmStmt::inputs_iterator E,
> - ExplodedNode* Pred, ExplodedNodeSet& Dst) {
> + ExplodedNode* Pred,
> + ExplodedNodeSet& Dst) {
> if (I == E) {
>
> // We have processed both the inputs and the outputs. All of the outputs
> @@ -2645,7 +2660,7 @@
>
> // Simulate the effects of a "store": bind the value of the RHS
> // to the L-Value represented by the LHS.
> - EvalStore(Tmp3, B, LHS, *I2, state->BindExpr(B, ExprVal), LeftV, RightV);
> + EvalStore(Tmp3, B, LHS, *I2, state->BindExpr(B, ExprVal), LeftV,RightV);
> continue;
> }
>
>
> Modified: cfe/trunk/lib/Analysis/MemRegion.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/MemRegion.cpp?rev=91535&r1=91534&r2=91535&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Analysis/MemRegion.cpp (original)
> +++ cfe/trunk/lib/Analysis/MemRegion.cpp Wed Dec 16 05:27:52 2009
> @@ -291,6 +291,17 @@
> BlockDataRegion::ProfileRegion(ID, BC, LC, getSuperRegion());
> }
>
> +void CXXObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
> + QualType T,
> + const MemRegion *sReg) {
> + ID.AddPointer(T.getTypePtr());
> + ID.AddPointer(sReg);
> +}
> +
> +void CXXObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
> + ProfileRegion(ID, T, getSuperRegion());
> +}
> +
> //===----------------------------------------------------------------------===//
> // Region pretty-printing.
> //===----------------------------------------------------------------------===//
> @@ -558,6 +569,11 @@
> return getSubRegion<ObjCObjectRegion>(d, superRegion);
> }
>
> +const CXXObjectRegion *
> +MemRegionManager::getCXXObjectRegion(QualType T) {
> + return getSubRegion<CXXObjectRegion>(T, getUnknownRegion());
> +}
> +
> const AllocaRegion*
> MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt,
> const LocationContext *LC) {
>
> Modified: cfe/trunk/lib/Analysis/RegionStore.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RegionStore.cpp?rev=91535&r1=91534&r2=91535&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Analysis/RegionStore.cpp (original)
> +++ cfe/trunk/lib/Analysis/RegionStore.cpp Wed Dec 16 05:27:52 2009
> @@ -746,6 +746,7 @@
> case MemRegion::ObjCIvarRegionKind:
> case MemRegion::ObjCObjectRegionKind:
> case MemRegion::SymbolicRegionKind:
> + case MemRegion::CXXObjectRegionKind:
> return UnknownVal();
>
> case MemRegion::StringRegionKind: {
> @@ -869,6 +870,7 @@
> case MemRegion::FieldRegionKind:
> case MemRegion::ObjCObjectRegionKind:
> case MemRegion::ObjCIvarRegionKind:
> + case MemRegion::CXXObjectRegionKind:
> return UnknownVal();
>
> case MemRegion::FunctionTextRegionKind:
>
> Modified: cfe/trunk/lib/Analysis/Store.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/Store.cpp?rev=91535&r1=91534&r2=91535&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Analysis/Store.cpp (original)
> +++ cfe/trunk/lib/Analysis/Store.cpp Wed Dec 16 05:27:52 2009
> @@ -106,6 +106,7 @@
> case MemRegion::FieldRegionKind:
> case MemRegion::ObjCIvarRegionKind:
> case MemRegion::VarRegionKind:
> + case MemRegion::CXXObjectRegionKind:
> return MakeElementRegion(R, PointeeTy);
>
> case MemRegion::ElementRegionKind: {
> @@ -240,3 +241,8 @@
> const LocationContext *LC) {
> return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL, LC));
> }
> +
> +Loc StoreManager::getThisObject(QualType T) {
> + const CXXObjectRegion *R = MRMgr.getCXXObjectRegion(T);
> + return loc::MemRegionVal(R);
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list