]> granicus.if.org Git - clang/commitdiff
Begin major changes to EvalXXX methods in GRTransferFuncs. Currently some of the...
authorTed Kremenek <kremenek@apple.com>
Thu, 17 Jul 2008 21:27:31 +0000 (21:27 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 17 Jul 2008 21:27:31 +0000 (21:27 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53739 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/GRTransferFuncs.cpp

index 1bae83b982db864da0a231b631291fc3f198945a..752f5cbe8a24a057993bed96ae9dbbd7598b6786 100644 (file)
@@ -609,6 +609,10 @@ protected:
       return TF->EvalBinOp(*this, Op, cast<NonLVal>(L), cast<NonLVal>(R));
   }
   
+  void EvalBinOp(ExplodedNodeSet<ValueState>& Dst, Expr* E,
+                 BinaryOperator::Opcode Op,
+                 NonLVal L, NonLVal R, ExplodedNode<ValueState>* Pred);
+  
   void EvalCall(NodeSet& Dst, CallExpr* CE, RVal L, NodeTy* Pred) {
     assert (Builder && "GRStmtNodeBuilder must be defined.");
     TF->EvalCall(Dst, *this, *Builder, CE, L, Pred);
index 4e267f8859e6c234a8c900a8ca44c35bb4cbc2fd..e5fa069c4582d425e83fa8a8813f6dd074474b01 100644 (file)
@@ -49,7 +49,16 @@ public:
   // Binary Operators.
   
   virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
-                         NonLVal L, NonLVal R) = 0;
+                         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 RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
                          LVal L, LVal R) = 0;
index ea86dfbf353e977cf2ba80901ef2d424728f8d7b..1a571f3c298d4d51091a304ae1a53cd280a08fa9 100644 (file)
@@ -185,6 +185,7 @@ template<> struct GRTrait<ValueState*> {
   
   
 class ValueStateManager {
+  friend class GRExprEngine;
   
 private:
   EnvironmentManager                   EnvMgr;
@@ -210,6 +211,13 @@ private:
   ///  This vector is persistent because it is reused over and over.
   StoreManager::DeclRootsTy DRoots;
   
+  /// CurrentStmt - The block-level statement currently being visited.  This
+  ///  is set by GRExprEngine.
+  Stmt* CurrentStmt;
+  
+  /// cfg - The CFG for the analyzed function/method.
+  CFG& cfg;
+  
 private:
 
   Environment RemoveBlkExpr(const Environment& Env, Expr* E) {
@@ -223,7 +231,7 @@ private:
     
 public:  
   ValueStateManager(ASTContext& Ctx, StoreManager* stmgr,
-                    llvm::BumpPtrAllocator& alloc) 
+                    llvm::BumpPtrAllocator& alloc, CFG& c
   : EnvMgr(alloc),
     StMgr(stmgr),
     ISetFactory(alloc), 
@@ -231,7 +239,8 @@ public:
     CEFactory(alloc),
     BasicVals(Ctx, alloc),
     SymMgr(alloc),
-    Alloc(alloc) {}
+    Alloc(alloc),
+    cfg(c) {}
 
   const ValueState* getInitialState();
         
@@ -273,6 +282,20 @@ public:
     NewSt.Env = NewEnv;
     return getPersistentState(NewSt);
   }
+  
+  const ValueState* SetRVal(const ValueState* St, Expr* Ex, RVal V) {
+    
+    bool isBlkExpr = false;
+    
+    if (Ex == CurrentStmt) {
+      isBlkExpr = cfg.isBlkExpr(Ex);
+      
+      if (!isBlkExpr)
+        return St;
+    }
+    
+    return SetRVal(St, Ex, V, isBlkExpr, true);
+  }
 
   // Methods that query & manipulate the Store.
 
index fa8009f3efc0dcfc4e497238df04d1c6850c7adb..e32fd0b331f102c8beeae4ed5d8783bcda44b8d9 100644 (file)
@@ -121,7 +121,7 @@ GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx,
     Liveness(L),
     Builder(NULL),
     StateMgr(G.getContext(), CreateBasicStoreManager(G.getAllocator()),
-             G.getAllocator()),
+             G.getAllocator(), G.getCFG()),
     BasicVals(StateMgr.getBasicValueFactory()),
     TF(NULL), // FIXME
     SymMgr(StateMgr.getSymbolManager()),
@@ -242,7 +242,10 @@ void GRExprEngine::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
   
   Builder = &builder;
   EntryNode = builder.getLastNode();
+  
+  // FIXME: Consolidate.
   CurrentStmt = S;
+  StateMgr.CurrentStmt = S;
   
   // Set up our simple checks.
   if (BatchAuditor)
@@ -296,7 +299,11 @@ void GRExprEngine::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
   // NULL out these variables to cleanup.
   CleanedState = NULL;
   EntryNode = NULL;
-  CurrentStmt = NULL;
+
+  // FIXME: Consolidate.
+  StateMgr.CurrentStmt = 0;
+  CurrentStmt = 0;
+  
   Builder = NULL;
 }
 
@@ -1802,8 +1809,13 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
             }
             else {
               nonlval::ConcreteInt X(BasicVals.getValue(0, Ex->getType()));
+#if 0            
               RVal Result = EvalBinOp(BinaryOperator::EQ, cast<NonLVal>(V), X);
               St = SetRVal(St, U, Result);
+#else
+              EvalBinOp(Dst, U, BinaryOperator::EQ, cast<NonLVal>(V), X, *I);
+              continue;
+#endif
             }
             
             break;
@@ -2225,6 +2237,31 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
   }
 }
 
+//===----------------------------------------------------------------------===//
+// Transfer-function Helpers.
+//===----------------------------------------------------------------------===//
+
+void GRExprEngine::EvalBinOp(ExplodedNodeSet<ValueState>& Dst, Expr* Ex,
+                             BinaryOperator::Opcode Op,
+                             NonLVal L, NonLVal R,
+                             ExplodedNode<ValueState>* Pred) {
+  
+  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);
+  
+  TF->EvalBinOpNN(Dst, *this, *Builder, Op, Ex, L, R, Pred);
+  
+  if (!Builder->BuildSinks && Dst.size() == size &&
+      !Builder->HasGeneratedNode)
+    MakeNode(Dst, Ex, Pred, GetState(Pred));
+}
+
 //===----------------------------------------------------------------------===//
 // "Assume" logic.
 //===----------------------------------------------------------------------===//
index a31f8aaa1b2e1a827b54a8d19859047226fd67ea..cf32a073c1ede703871e0c972e945e9ec62210ee 100644 (file)
@@ -37,3 +37,18 @@ void GRTransferFuncs::EvalStore(ExplodedNodeSet<ValueState>& Dst,
     Builder.MakeNode(Dst, E, Pred,
                 Eng.getStateManager().SetRVal(St, cast<LVal>(TargetLV), Val));    
 }
+
+void GRTransferFuncs::EvalBinOpNN(ExplodedNodeSet<ValueState>& Dst,
+                                  GRExprEngine& Engine,
+                                  GRStmtNodeBuilder<ValueState>& Builder,
+                                  BinaryOperator::Opcode Op,
+                                  Expr* Ex,
+                                  NonLVal L, NonLVal R,
+                                  ExplodedNode<ValueState>* Pred) {
+
+  ValueStateManager& StateMgr = Engine.getStateManager();
+  const ValueState* St = Builder.GetState(Pred);
+  
+  RVal Result = EvalBinOp(Engine, Op, L, R);
+  Builder.MakeNode(Dst, Ex, Pred, StateMgr.SetRVal(St, Ex, Result));
+}