aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngine.h4
-rw-r--r--include/clang/Analysis/PathSensitive/GRState.h8
-rw-r--r--include/clang/Analysis/PathSensitive/Store.h9
-rw-r--r--lib/Analysis/BasicStore.cpp5
-rw-r--r--lib/Analysis/GRExprEngine.cpp33
-rw-r--r--lib/Analysis/GRState.cpp20
-rw-r--r--lib/Analysis/RegionStore.cpp9
7 files changed, 88 insertions, 0 deletions
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h
index 8c5e6ed403..22454810be 100644
--- a/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h
@@ -499,6 +499,10 @@ protected:
/// VisitCast - Transfer function logic for all casts (implicit and explicit).
void VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst);
+ /// VisitCompoundLiteralExpr - Transfer function logic for compound literals.
+ void VisitCompoundLiteralExpr(CompoundLiteralExpr* CL, NodeTy* Pred,
+ NodeSet& Dst);
+
/// VisitDeclRefExpr - Transfer function logic for DeclRefExprs.
void VisitDeclRefExpr(DeclRefExpr* DR, NodeTy* Pred, NodeSet& Dst,
bool asLValue);
diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h
index d9b058ce84..265d028e8a 100644
--- a/include/clang/Analysis/PathSensitive/GRState.h
+++ b/include/clang/Analysis/PathSensitive/GRState.h
@@ -329,6 +329,14 @@ public:
const GRState* AddDecl(const GRState* St, const VarDecl* VD, Expr* Ex,
unsigned Count);
+
+ /// BindCompoundLiteral - Return the state that has the bindings currently
+ /// in 'state' plus the bindings for the CompoundLiteral. 'R' is the region
+ /// for the compound literal and 'BegInit' and 'EndInit' represent an
+ /// array of initializer values.
+ const GRState* BindCompoundLiteral(const GRState* state,
+ const CompoundLiteralRegion* R,
+ const SVal* BegInit, const SVal* EndInit);
const GRState* RemoveDeadBindings(const GRState* St, Stmt* Loc,
const LiveVariables& Liveness,
diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h
index 7610c54e1b..41464c176f 100644
--- a/include/clang/Analysis/PathSensitive/Store.h
+++ b/include/clang/Analysis/PathSensitive/Store.h
@@ -47,6 +47,15 @@ public:
virtual Store Bind(Store St, Loc LV, SVal V) = 0;
virtual Store Remove(Store St, Loc LV) = 0;
+
+ /// BindCompoundLiteral - Return the store that has the bindings currently
+ /// in 'store' plus the bindings for the CompoundLiteral. 'R' is the region
+ /// for the compound literal and 'BegInit' and 'EndInit' represent an
+ /// array of initializer values.
+ virtual Store BindCompoundLiteral(Store store, const CompoundLiteralRegion* R,
+ const SVal* BegInit,
+ const SVal* EndInit) = 0;
+
virtual Store getInitialStore() = 0;
virtual MemRegionManager& getRegionManager() = 0;
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp
index 8895954502..05c8523d2d 100644
--- a/lib/Analysis/BasicStore.cpp
+++ b/lib/Analysis/BasicStore.cpp
@@ -46,6 +46,11 @@ public:
return loc::MemRegionVal(MRMgr.getVarRegion(VD));
}
+ Store BindCompoundLiteral(Store store, const CompoundLiteralRegion* R,
+ const SVal* BegInit, const SVal* EndInit) {
+ return store;
+ }
+
SVal getLValueVar(const GRState* St, const VarDecl* VD);
SVal getLValueString(const GRState* St, const StringLiteral* S);
SVal getLValueIvar(const GRState* St, const ObjCIvarDecl* D, SVal Base);
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 282a08c21a..67dd79a193 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -430,6 +430,10 @@ void GRExprEngine::VisitLValue(Expr* Ex, NodeTy* Pred, NodeSet& Dst) {
VisitMemberExpr(cast<MemberExpr>(Ex), Pred, Dst, true);
return;
+ case Stmt::CompoundLiteralExprClass:
+ VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(Ex), Pred, Dst);
+ return;
+
case Stmt::ObjCPropertyRefExprClass:
// FIXME: Property assignments are lvalues, but not really "locations".
// e.g.: self.x = something;
@@ -1530,6 +1534,35 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){
}
}
+void GRExprEngine::VisitCompoundLiteralExpr(CompoundLiteralExpr* CL,
+ NodeTy* Pred, NodeSet& Dst) {
+
+ // FIXME: Can getInitializer() be NULL?
+ InitListExpr* ILE = cast<InitListExpr>(CL->getInitializer()->IgnoreParens());
+ NodeSet Tmp;
+ Visit(ILE, Pred, Tmp);
+
+ for (NodeSet::iterator I = Tmp.begin(), EI = Tmp.end(); I!=EI; ++I) {
+ // Retrieve the initializer values from the environment and store them
+ // into a vector that will then be handed off to the Store.
+ const GRState* St = GetState(*I);
+ llvm::SmallVector<SVal, 10> IVals;
+ IVals.reserve(ILE->getNumInits());
+
+ for (Stmt::child_iterator J=ILE->child_begin(), EJ=ILE->child_end();
+ J!=EJ; ++J)
+ IVals.push_back(GetSVal(St, cast<Expr>(*J)));
+
+ const CompoundLiteralRegion* R =
+ StateMgr.getRegionManager().getCompoundLiteralRegion(CL);
+
+ assert (!IVals.empty() && "Initializer cannot be empty.");
+
+ St = StateMgr.BindCompoundLiteral(St, R, &IVals[0], &IVals[0]+IVals.size());
+ MakeNode(Dst, CL, *I, SetSVal(St, CL, loc::MemRegionVal(R)));
+ }
+}
+
void GRExprEngine::VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst) {
// The CFG has one DeclStmt per Decl.
diff --git a/lib/Analysis/GRState.cpp b/lib/Analysis/GRState.cpp
index 828be2229f..03b724779e 100644
--- a/lib/Analysis/GRState.cpp
+++ b/lib/Analysis/GRState.cpp
@@ -92,6 +92,26 @@ const GRState* GRStateManager::AddDecl(const GRState* St, const VarDecl* VD,
return getPersistentState(NewSt);
}
+/// BindCompoundLiteral - Return the store that has the bindings currently
+/// in 'store' plus the bindings for the CompoundLiteral. 'R' is the region
+/// for the compound literal and 'BegInit' and 'EndInit' represent an
+/// array of initializer values.
+const GRState*
+GRStateManager::BindCompoundLiteral(const GRState* state,
+ const CompoundLiteralRegion* R,
+ const SVal* BegInit, const SVal* EndInit) {
+
+ Store oldStore = state->getStore();
+ Store newStore = StoreMgr->BindCompoundLiteral(oldStore, R, BegInit, EndInit);
+
+ if (newStore == oldStore)
+ return state;
+
+ GRState newState = *state;
+ newState.St = newStore;
+ return getPersistentState(newState);
+}
+
const GRState* GRStateManager::Unbind(const GRState* St, Loc LV) {
Store OldStore = St->getStore();
Store NewStore = StoreMgr->Remove(OldStore, LV);
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index 6a65919b1e..1c73ceae20 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -45,6 +45,15 @@ public:
SVal GetRegionSVal(Store St, const MemRegion* R) {
return Retrieve(St, loc::MemRegionVal(R));
}
+
+ Store BindCompoundLiteral(Store store, const CompoundLiteralRegion* R,
+ const SVal* BegInit, const SVal* EndInit) {
+
+ // FIXME: Let's discuss how we want to do the mapping in RegionStore
+ // from CompoundLiteralRegion to values.
+ assert (false && "Not yet implemented.");
+ return store;
+ }
SVal getLValueString(const GRState* St, const StringLiteral* S);