aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2009-12-16 11:27:52 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2009-12-16 11:27:52 +0000
commitbb141217871e93767aa3f2de1b9946fa6d37066a (patch)
tree4eca9b4297f4a6723c6945cb29833c7c207ef134
parent578b69b186d9cba0a6ae1dd7f4c04cd6a49f0aac (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91535 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngine.h26
-rw-r--r--include/clang/Analysis/PathSensitive/MemRegion.h29
-rw-r--r--include/clang/Analysis/PathSensitive/Store.h3
-rw-r--r--lib/Analysis/GRExprEngine.cpp45
-rw-r--r--lib/Analysis/MemRegion.cpp16
-rw-r--r--lib/Analysis/RegionStore.cpp2
-rw-r--r--lib/Analysis/Store.cpp6
7 files changed, 102 insertions, 25 deletions
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h
index 518c8a0b60..da95a1cf4c 100644
--- a/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h
@@ -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 @@ protected:
}
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 @@ protected:
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 @@ protected:
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 @@ public:
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,
diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h
index 2fe5ea0cf3..f0ae39498e 100644
--- a/include/clang/Analysis/PathSensitive/MemRegion.h
+++ b/include/clang/Analysis/PathSensitive/MemRegion.h
@@ -73,7 +73,8 @@ public:
FieldRegionKind,
ObjCIvarRegionKind,
ObjCObjectRegionKind,
- END_DECL_REGIONS = ObjCObjectRegionKind,
+ CXXObjectRegionKind,
+ END_DECL_REGIONS = CXXObjectRegionKind,
END_TYPED_REGIONS = END_DECL_REGIONS
};
@@ -752,6 +753,30 @@ public:
}
};
+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 @@ public:
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,
diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h
index 648710f7ad..fcc1cd306b 100644
--- a/include/clang/Analysis/PathSensitive/Store.h
+++ b/include/clang/Analysis/PathSensitive/Store.h
@@ -103,6 +103,9 @@ public:
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) {
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index a0ec87d2f7..f93ed7871b 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -506,7 +506,6 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
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 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
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 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
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 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
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 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
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::ProcessIndirectGoto(GRIndirectGotoNodeBuilder& builder) {
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 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
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 @@ void GRExprEngine::VisitDeclStmt(DeclStmt *DS, ExplodedNode *Pred,
}
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 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
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 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
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 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
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::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
}
}
-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 @@ void GRExprEngine::VisitAsmStmtHelperOutputs(AsmStmt* A,
++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 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
// 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;
}
diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp
index bc3a5b7045..04d730c5c8 100644
--- a/lib/Analysis/MemRegion.cpp
+++ b/lib/Analysis/MemRegion.cpp
@@ -291,6 +291,17 @@ void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
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 @@ MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
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) {
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index bc3680e23d..b83ddf224b 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -746,6 +746,7 @@ DefinedOrUnknownSVal RegionStoreManager::getSizeInElements(const GRState *state,
case MemRegion::ObjCIvarRegionKind:
case MemRegion::ObjCObjectRegionKind:
case MemRegion::SymbolicRegionKind:
+ case MemRegion::CXXObjectRegionKind:
return UnknownVal();
case MemRegion::StringRegionKind: {
@@ -869,6 +870,7 @@ SVal RegionStoreManager::EvalBinOp(const GRState *state,
case MemRegion::FieldRegionKind:
case MemRegion::ObjCObjectRegionKind:
case MemRegion::ObjCIvarRegionKind:
+ case MemRegion::CXXObjectRegionKind:
return UnknownVal();
case MemRegion::FunctionTextRegionKind:
diff --git a/lib/Analysis/Store.cpp b/lib/Analysis/Store.cpp
index 56f8a0a70c..0479c684d7 100644
--- a/lib/Analysis/Store.cpp
+++ b/lib/Analysis/Store.cpp
@@ -106,6 +106,7 @@ const MemRegion *StoreManager::CastRegion(const MemRegion *R, QualType CastToTy)
case MemRegion::FieldRegionKind:
case MemRegion::ObjCIvarRegionKind:
case MemRegion::VarRegionKind:
+ case MemRegion::CXXObjectRegionKind:
return MakeElementRegion(R, PointeeTy);
case MemRegion::ElementRegionKind: {
@@ -240,3 +241,8 @@ SVal StoreManager::getLValueCompoundLiteral(const CompoundLiteralExpr* CL,
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);
+}