]> granicus.if.org Git - clang/commitdiff
Created ValueStateSet class to manage the creation of multiple states by a method.
authorTed Kremenek <kremenek@apple.com>
Fri, 18 Jul 2008 05:53:58 +0000 (05:53 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 18 Jul 2008 05:53:58 +0000 (05:53 +0000)
Modified the new EvalBinOpNN to generate states instead of nodes.  This is a much simpler interface and is what clients will want to do.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53750 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/PathSensitive/GRExprEngine.h
include/clang/Analysis/PathSensitive/GRTransferFuncs.h
include/clang/Analysis/PathSensitive/ValueState.h
lib/Analysis/GRExprEngine.cpp
lib/Analysis/GRSimpleVals.cpp
lib/Analysis/GRSimpleVals.h
lib/Analysis/GRTransferFuncs.cpp

index 0102f55cfebfc5cc739e6b1beb448f3b47a7083c..4a04247139b74e4433f82e1f664b397c9646b7df 100644 (file)
@@ -67,9 +67,6 @@ protected:
   /// StateMgr - Object that manages the data for all created states.
   ValueStateManager StateMgr;
   
-  /// ValueMgr - Object that manages the data for all created RVals.
-  BasicValueFactory& BasicVals;
-  
   /// BugTypes - Objects used for reporting bugs.
   typedef std::vector<BugType*> BugTypeSet;
   BugTypeSet BugTypes;
@@ -375,8 +372,12 @@ public:
   ValueStateManager& getStateManager() { return StateMgr; }
   const ValueStateManager& getStateManger() const { return StateMgr; }
   
-  BasicValueFactory& getBasicVals() { return BasicVals; }
-  const BasicValueFactory& getBasicVals() const { return BasicVals; }
+  BasicValueFactory& getBasicVals() {
+    return StateMgr.getBasicVals();
+  }
+  const BasicValueFactory& getBasicVals() const {
+    return StateMgr.getBasicVals();
+  }
   
   SymbolManager& getSymbolManager() { return SymMgr; }
   const SymbolManager& getSymbolManager() const { return SymMgr; }
@@ -424,7 +425,7 @@ protected:
   }
   
   inline NonLVal MakeConstantVal(uint64_t X, Expr* Ex) {
-    return NonLVal::MakeVal(BasicVals, X, Ex->getType());
+    return NonLVal::MakeVal(getBasicVals(), X, Ex->getType());
   }
   
   /// Assume - Create new state by assuming that a given expression
@@ -545,15 +546,22 @@ protected:
   RVal EvalComplement(RVal X) {
     return X.isValid() ? getTF().EvalComplement(*this, cast<NonLVal>(X)) : X;
   }
+  
+  RVal EvalBinOp(BinaryOperator::Opcode Op, NonLVal L, NonLVal R) {
+    return R.isValid() ? getTF().EvalBinOp(getStateManager(), Op, L, R) : R;
+  }
 
   RVal EvalBinOp(BinaryOperator::Opcode Op, NonLVal L, RVal R) {
-    return R.isValid() ? getTF().EvalBinOp(*this, Op, L, cast<NonLVal>(R)) : R;
+    return R.isValid() ? getTF().EvalBinOp(getStateManager(), Op, L,
+                                           cast<NonLVal>(R)) : R;
   }
   
-  void EvalBinOp(ExplodedNodeSet<ValueState>& Dst, Expr* E,
+  void EvalBinOp(ExplodedNodeSet<ValueState>& Dst, Expr* Ex,
                  BinaryOperator::Opcode Op, NonLVal L, NonLVal R,
                  ExplodedNode<ValueState>* Pred);
   
+  void EvalBinOp(ValueStateSet& OStates, const ValueState* St, Expr* Ex,
+                 BinaryOperator::Opcode Op, NonLVal L, NonLVal R);  
   
   RVal EvalBinOp(BinaryOperator::Opcode Op, RVal L, RVal R) {
 
@@ -577,10 +585,12 @@ protected:
       assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub);
 
       // Commute the operands.
-      return getTF().EvalBinOp(*this, Op, cast<LVal>(R), cast<NonLVal>(L));
+      return getTF().EvalBinOp(*this, Op, cast<LVal>(R),
+                               cast<NonLVal>(L));
     }
     else
-      return getTF().EvalBinOp(*this, Op, cast<NonLVal>(L), cast<NonLVal>(R));
+      return getTF().EvalBinOp(getStateManager(), Op, cast<NonLVal>(L),
+                               cast<NonLVal>(R));
   }
   
   
index b57244ae04c6ff5a00a4703142ce4a2127007c2f..db7de8162144b4d7546522e7aa90d2e699396352 100644 (file)
@@ -48,17 +48,14 @@ public:
 
   // Binary Operators.
   
-  virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
+  virtual RVal EvalBinOp(ValueStateManager& StateMgr, BinaryOperator::Opcode Op,
                          NonLVal L, NonLVal R) {
     return UnknownVal();
   }
   
-  virtual void EvalBinOpNN(ExplodedNodeSet<ValueState>& Dst,
-                           GRExprEngine& Engine,
-                           GRStmtNodeBuilder<ValueState>& Builder,
-                           BinaryOperator::Opcode Op, Expr* Ex,
-                           NonLVal L, NonLVal R,
-                           ExplodedNode<ValueState>* Pred);
+  virtual void EvalBinOpNN(ValueStateSet& OStates, ValueStateManager& StateMgr,
+                           const ValueState* St, Expr* Ex,
+                           BinaryOperator::Opcode Op, NonLVal L, NonLVal R);
   
   virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
                          LVal L, LVal R) = 0;
index c508d6f4cd3507e76746b8d88c0fc03911b3bb18..3a56abe81b3ced43b6cbef7fe221e87ace23593a 100644 (file)
@@ -184,6 +184,38 @@ template<> struct GRTrait<ValueState*> {
   }
 };
   
+class ValueStateSet {
+  typedef llvm::SmallPtrSet<const ValueState*,5> ImplTy;
+  ImplTy Impl;  
+public:
+  ValueStateSet() {}
+
+  inline void Add(const ValueState* St) {
+    Impl.insert(St);
+  }
+  
+  typedef ImplTy::const_iterator iterator;
+  
+  inline unsigned size() const { return Impl.size();  }
+  inline bool empty()    const { return Impl.empty(); }
+  
+  inline iterator begin() const { return Impl.begin(); }
+  inline iterator end() const { return Impl.end();   }
+  
+  class AutoPopulate {
+    ValueStateSet& S;
+    unsigned StartSize;
+    const ValueState* St;
+  public:
+    AutoPopulate(ValueStateSet& s, const ValueState* st) 
+      : S(s), StartSize(S.size()), St(st) {}
+    
+    ~AutoPopulate() {
+      if (StartSize == S.size())
+        S.Add(St);
+    }
+  };
+};
   
 class ValueStateManager {
   friend class GRExprEngine;
@@ -249,7 +281,8 @@ public:
 
   const ValueState* getInitialState();
         
-  BasicValueFactory& getBasicValueFactory() { return BasicVals; }
+  BasicValueFactory& getBasicVals() { return BasicVals; }
+  const BasicValueFactory& getBasicVals() const { return BasicVals; }
   SymbolManager& getSymbolManager() { return SymMgr; }
   
   typedef StoreManager::DeadSymbolsTy DeadSymbolsTy;
index c4278b1e5b134303f084c7577901442d1efbe755..f3caaa5ad3a7fbbb30b82856c6889c992169be2b 100644 (file)
@@ -122,7 +122,6 @@ GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx,
     Builder(NULL),
     StateMgr(G.getContext(), CreateBasicStoreManager(G.getAllocator()),
              G.getAllocator(), G.getCFG()),
-    BasicVals(StateMgr.getBasicValueFactory()),
     SymMgr(StateMgr.getSymbolManager()),
     CurrentStmt(NULL),
   NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
@@ -707,7 +706,7 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) {
     //  This should be easy once we have "ranges" for NonLVals.
         
     do {
-      nonlval::ConcreteInt CaseVal(BasicVals.getValue(V1));
+      nonlval::ConcreteInt CaseVal(getBasicVals().getValue(V1));
       
       RVal Res = EvalBinOp(BinaryOperator::EQ, CondV, CaseVal);
       
@@ -823,7 +822,7 @@ void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* D, NodeTy* Pred, NodeSet& Dst,
                                     bool asLVal) {
   
   const ValueState* St = GetState(Pred);
-  RVal X = RVal::MakeVal(BasicVals, D);
+  RVal X = RVal::MakeVal(getBasicVals(), D);
   
   if (asLVal)
     MakeNode(Dst, D, Pred, SetRVal(St, D, cast<LVal>(X)));
@@ -869,7 +868,7 @@ void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A, NodeTy* Pred,
       if (nonlval::ConcreteInt* IdxInt = dyn_cast<nonlval::ConcreteInt>(&IdxV))        
         useBase = IdxInt->getValue() == 0;
       
-      RVal V = useBase ? BaseV : lval::ArrayOffset::Make(BasicVals, BaseV,IdxV);
+      RVal V = useBase ? BaseV : lval::ArrayOffset::Make(getBasicVals(), BaseV,IdxV);
 
       if (asLVal)
         MakeNode(Dst, A, *I2, SetRVal(St, A, V));
@@ -900,7 +899,7 @@ void GRExprEngine::VisitMemberExpr(MemberExpr* M, NodeTy* Pred,
       const ValueState* St = GetState(*I);
       RVal BaseV = GetRVal(St, Base);      
       
-      RVal V = lval::FieldOffset::Make(BasicVals, GetRVal(St, Base),
+      RVal V = lval::FieldOffset::Make(getBasicVals(), GetRVal(St, Base),
                                        M->getMemberDecl());
       
       MakeNode(Dst, M, *I, SetRVal(St, M, V));
@@ -922,7 +921,7 @@ void GRExprEngine::VisitMemberExpr(MemberExpr* M, NodeTy* Pred,
     
       assert (M->isArrow());
       
-      RVal V = lval::FieldOffset::Make(BasicVals, GetRVal(St, Base),
+      RVal V = lval::FieldOffset::Make(getBasicVals(), GetRVal(St, Base),
                                        M->getMemberDecl());
     
       EvalLoad(Dst, M, *I, St, V);
@@ -1461,7 +1460,7 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){
       // equal or exceeds the number of bits to store the pointer value.
       // If not, flag an error.
       
-      V = nonlval::LValAsInteger::Make(BasicVals, cast<LVal>(V), bits);
+      V = nonlval::LValAsInteger::Make(getBasicVals(), cast<LVal>(V), bits);
       MakeNode(Dst, CastE, N, SetRVal(St, CastE, V));
       continue;
     }
@@ -1548,10 +1547,10 @@ void GRExprEngine::VisitDeclStmtAux(DeclStmt* DS, ScopedDecl* D,
         
         if (LVal::IsLValType(T))
           St = SetRVal(St, lval::DeclVal(VD),
-                       lval::ConcreteInt(BasicVals.getValue(0, T)));
+                       lval::ConcreteInt(getBasicVals().getValue(0, T)));
         else if (T->isIntegerType())
           St = SetRVal(St, lval::DeclVal(VD),
-                       nonlval::ConcreteInt(BasicVals.getValue(0, T)));          
+                       nonlval::ConcreteInt(getBasicVals().getValue(0, T)));          
           
         // FIXME: Handle structs.  Now we treat them as unknown.  What
         //  we need to do is treat their members as unknown.
@@ -1626,7 +1625,7 @@ void GRExprEngine::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr* Ex,
   
   MakeNode(Dst, Ex, Pred,
            SetRVal(GetState(Pred), Ex,
-                   NonLVal::MakeVal(BasicVals, amt, Ex->getType())));  
+                   NonLVal::MakeVal(getBasicVals(), amt, Ex->getType())));  
 }
 
 
@@ -1699,7 +1698,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
         // For all other types, UnaryOperator::Float returns 0.
         assert (Ex->getType()->isIntegerType());
         const ValueState* St = GetState(*I);
-        RVal X = NonLVal::MakeVal(BasicVals, 0, Ex->getType());
+        RVal X = NonLVal::MakeVal(getBasicVals(), 0, Ex->getType());
         MakeNode(Dst, U, *I, SetRVal(St, U, X));
       }
       
@@ -1787,12 +1786,12 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
             //    transfer functions as "0 == E".
             
             if (isa<LVal>(V)) {
-              lval::ConcreteInt X(BasicVals.getZeroWithPtrWidth());
+              lval::ConcreteInt X(getBasicVals().getZeroWithPtrWidth());
               RVal Result = EvalBinOp(BinaryOperator::EQ, cast<LVal>(V), X);
               St = SetRVal(St, U, Result);
             }
             else {
-              nonlval::ConcreteInt X(BasicVals.getValue(0, Ex->getType()));
+              nonlval::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
 #if 0            
               RVal Result = EvalBinOp(BinaryOperator::EQ, cast<NonLVal>(V), X);
               St = SetRVal(St, U, Result);
@@ -1822,7 +1821,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
         
       uint64_t size = getContext().getTypeSize(T) / 8;                
       const ValueState* St = GetState(Pred);
-      St = SetRVal(St, U, NonLVal::MakeVal(BasicVals, size, U->getType()));
+      St = SetRVal(St, U, NonLVal::MakeVal(getBasicVals(), size, U->getType()));
         
       MakeNode(Dst, U, Pred, St);
       return;
@@ -2229,21 +2228,20 @@ void GRExprEngine::EvalBinOp(ExplodedNodeSet<ValueState>& Dst, Expr* Ex,
                              BinaryOperator::Opcode Op,
                              NonLVal L, NonLVal R,
                              ExplodedNode<ValueState>* Pred) {
+
+  ValueStateSet OStates;
+  EvalBinOp(OStates, GetState(Pred), Ex, Op, L, R);
+
+  for (ValueStateSet::iterator I=OStates.begin(), E=OStates.end(); I!=E; ++I)
+    MakeNode(Dst, Ex, Pred, *I);
+}
+
+void GRExprEngine::EvalBinOp(ValueStateSet& OStates, const ValueState* St,
+                             Expr* Ex, BinaryOperator::Opcode Op,
+                             NonLVal L, NonLVal R) {
   
-  if (!R.isValid()) {
-    MakeNode(Dst, Ex, Pred, SetRVal(GetState(Pred), Ex, R));
-    return;
-  }
-  
-  assert (Builder && "GRStmtNodeBuilder must be defined.");    
-  unsigned size = Dst.size();
-  SaveOr OldHasGen(Builder->HasGeneratedNode);
-  
-  getTF().EvalBinOpNN(Dst, *this, *Builder, Op, Ex, L, R, Pred);
-  
-  if (!Builder->BuildSinks && Dst.size() == size &&
-      !Builder->HasGeneratedNode)
-    MakeNode(Dst, Ex, Pred, GetState(Pred));
+  ValueStateSet::AutoPopulate AP(OStates, St);
+  if (R.isValid()) getTF().EvalBinOpNN(OStates, StateMgr, St, Ex, Op, L, R);
 }
 
 //===----------------------------------------------------------------------===//
index e3ba0f3c4abbf12638d19a5a4fbbe832e38b9957..f95ccb564f729730827f1f55ca760cedb03f6e6e 100644 (file)
@@ -450,10 +450,10 @@ RVal GRSimpleVals::EvalComplement(GRExprEngine& Eng, NonLVal X) {
 
 // Binary operators.
 
-RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
-                             NonLVal L, NonLVal R)  {
+RVal GRSimpleVals::EvalBinOp(ValueStateManager& StateMgr,
+                             BinaryOperator::Opcode Op, NonLVal L, NonLVal R)  {
   
-  BasicValueFactory& BasicVals = Eng.getBasicVals();
+  BasicValueFactory& BasicVals = StateMgr.getBasicVals();
   
   while (1) {
     
index d86db51511cdcb3b4b1ab39c45b4dd995c6d0a9e..fc20c3e5bc8cfae67daaae3a7a0efebd6d638999 100644 (file)
@@ -44,7 +44,7 @@ public:
   
   // Binary Operators.
   
-  virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
+  virtual RVal EvalBinOp(ValueStateManager& StateMgr, BinaryOperator::Opcode Op,
                          NonLVal L, NonLVal R);
   
   virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
index cf32a073c1ede703871e0c972e945e9ec62210ee..9d9c97f0edf8998f93e3e7bf5245d201e9cfaadb 100644 (file)
@@ -38,17 +38,11 @@ void GRTransferFuncs::EvalStore(ExplodedNodeSet<ValueState>& Dst,
                 Eng.getStateManager().SetRVal(St, cast<LVal>(TargetLV), Val));    
 }
 
-void GRTransferFuncs::EvalBinOpNN(ExplodedNodeSet<ValueState>& Dst,
-                                  GRExprEngine& Engine,
-                                  GRStmtNodeBuilder<ValueState>& Builder,
+void GRTransferFuncs::EvalBinOpNN(ValueStateSet& OStates,
+                                  ValueStateManager& StateMgr,
+                                  const ValueState *St, Expr* Ex,
                                   BinaryOperator::Opcode Op,
-                                  Expr* Ex,
-                                  NonLVal L, NonLVal R,
-                                  ExplodedNode<ValueState>* Pred) {
-
-  ValueStateManager& StateMgr = Engine.getStateManager();
-  const ValueState* St = Builder.GetState(Pred);
+                                  NonLVal L, NonLVal R) {
   
-  RVal Result = EvalBinOp(Engine, Op, L, R);
-  Builder.MakeNode(Dst, Ex, Pred, StateMgr.SetRVal(St, Ex, Result));
+  OStates.Add(StateMgr.SetRVal(St, Ex, EvalBinOp(StateMgr, Op, L, R)));
 }