Added preliminary support for CompoundLiterals in the static analyzer:
- GRExprEngine::VisitCompoundLiteral...
(1) visits the initializer list (generating ExplodedNodes)
(2) creates a CompoundMemRegion for the literal
(3) creates a new state with the bound literal values using
GRStateManager::BindCompoundLiteral
- GRStateManager::BindCompoundLiteral simply calls
StoreManager::BindCompoundLiteral to get a new store and returns a persistent
GRState with that store.
- BasicStore::BindCompoundLiteral simply returns the same store, as it
doesn't handle field sensitivity
- RegionStore::BindCompoundLiteral currently fires an assert (pending discussion
of how to best implement mappings for CompoundLiteralRegion).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58277 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 282a08c..67dd79a 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -430,6 +430,10 @@
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::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.