[cfe-commits] r49811 - in /cfe/trunk: include/clang/Analysis/PathSensitive/GRExprEngine.h include/clang/Analysis/PathSensitive/GRTransferFuncs.h lib/Analysis/CFRefCount.cpp lib/Analysis/GRExprEngine.cpp lib/Analysis/GRTransferFuncs.cpp

Ted Kremenek kremenek at apple.com
Wed Apr 16 13:40:59 PDT 2008


Author: kremenek
Date: Wed Apr 16 15:40:59 2008
New Revision: 49811

URL: http://llvm.org/viewvc/llvm-project?rev=49811&view=rev
Log:
Small tweaks to EvalStore: pass an "RVal" instead of "LVal" for the TargetLV to
represent possible stores to "Unknown."

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
    cfe/trunk/lib/Analysis/CFRefCount.cpp
    cfe/trunk/lib/Analysis/GRExprEngine.cpp
    cfe/trunk/lib/Analysis/GRTransferFuncs.cpp

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=49811&r1=49810&r2=49811&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Wed Apr 16 15:40:59 2008
@@ -603,10 +603,10 @@
   }
   
   void VisitStore(NodeSet& Dst, Expr* E, NodeTy* Pred, ValueState* St,
-                 LVal TargetLV, RVal Val);
+                 RVal TargetLV, RVal Val);
   
   void EvalStore(NodeSet& Dst, Expr* E, NodeTy* Pred, ValueState* St,
-                 LVal TargetLV, RVal Val) {
+                 RVal TargetLV, RVal Val) {
     TF->EvalStore(Dst, *this, *Builder, E, Pred, St, TargetLV, Val);
   }
   

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h?rev=49811&r1=49810&r2=49811&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h Wed Apr 16 15:40:59 2008
@@ -74,11 +74,14 @@
   
   // Stores.
   
+  /// EvalStore - Evaluate the effects of a store, creating a new node
+  ///  the represents the effect of binding 'Val' to the location 'TargetLV'.
+  //   TargetLV is guaranteed to either be an UnknownVal or an LVal.
   virtual void EvalStore(ExplodedNodeSet<ValueState>& Dst,
                          GRExprEngine& Engine,
                          GRStmtNodeBuilder<ValueState>& Builder,
                          Expr* E, ExplodedNode<ValueState>* Pred,
-                         ValueState* St, LVal TargetLV, RVal Val) {}
+                         ValueState* St, RVal TargetLV, RVal Val);
                          
   
   // End-of-path.

Modified: cfe/trunk/lib/Analysis/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFRefCount.cpp?rev=49811&r1=49810&r2=49811&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Wed Apr 16 15:40:59 2008
@@ -455,14 +455,9 @@
 } // end anonymous namespace
 
 //===----------------------------------------------------------------------===//
-// Transfer functions.
+// Reference-counting logic (typestate + counts).
 //===----------------------------------------------------------------------===//
 
-static inline Selector GetUnarySelector(const char* name, ASTContext& Ctx) {
-  IdentifierInfo* II = &Ctx.Idents.get(name);
-  return Ctx.Selectors.getSelector(0, &II);
-}
-
 namespace {
   
 class VISIBILITY_HIDDEN RefVal {
@@ -543,6 +538,15 @@
   }
 }
   
+//===----------------------------------------------------------------------===//
+// Transfer functions.
+//===----------------------------------------------------------------------===//
+
+static inline Selector GetUnarySelector(const char* name, ASTContext& Ctx) {
+  IdentifierInfo* II = &Ctx.Idents.get(name);
+  return Ctx.Selectors.getSelector(0, &II);
+}
+  
 class VISIBILITY_HIDDEN CFRefCount : public GRSimpleVals {
   
   // Type definitions.
@@ -597,6 +601,7 @@
                     RefVal::Kind hasErr);
   
 public:
+  
   CFRefCount(ASTContext& Ctx)
     : Summaries(Ctx),
       RetainSelector(GetUnarySelector("retain", Ctx)),
@@ -630,6 +635,13 @@
                               ObjCMessageExpr* ME,
                               ExplodedNode<ValueState>* Pred);
 
+  // Stores.
+  
+  virtual void EvalStore(ExplodedNodeSet<ValueState>& Dst,
+                         GRExprEngine& Engine,
+                         GRStmtNodeBuilder<ValueState>& Builder,
+                         Expr* E, ExplodedNode<ValueState>* Pred,
+                         ValueState* St, RVal TargetLV, RVal Val);
   // End-of-path.
   
   virtual void EvalEndPath(GRExprEngine& Engine,
@@ -916,6 +928,49 @@
   return false;
 }
 
+// Stores.
+
+void CFRefCount::EvalStore(ExplodedNodeSet<ValueState>& Dst,
+                           GRExprEngine& Eng,
+                           GRStmtNodeBuilder<ValueState>& Builder,
+                           Expr* E, ExplodedNode<ValueState>* Pred,
+                           ValueState* St, RVal TargetLV, RVal Val) {
+  
+  // Check if we have a binding for "Val" and if we are storing it to something
+  // we don't understand or otherwise the value "escapes" the function.
+  
+  if (!isa<lval::SymbolVal>(Val))
+    return;
+  
+  // Are we storing to something that causes the value to "escape"?
+  
+  bool escapes = false;
+  
+  if (!isa<lval::DeclVal>(TargetLV))
+    escapes = true;
+  else
+    escapes = cast<lval::DeclVal>(TargetLV).getDecl()->hasGlobalStorage();
+  
+  if (!escapes)
+    return;
+  
+  SymbolID Sym = cast<lval::SymbolVal>(Val).getSymbol();
+  RefBindings B = GetRefBindings(*St);
+  RefBindings::TreeTy* T = B.SlimFind(Sym);
+  
+  if (!T)
+    return;
+  
+  // Nuke the binding.
+  
+  ValueState StImpl = *St;
+  StImpl.CheckerState = RefBFactory.Remove(B, Sym).getRoot();
+  St = Eng.getStateManager().getPersistentState(StImpl);
+  
+  // Hand of the remaining logic to the parent implementation.
+  GRSimpleVals::EvalStore(Dst, Eng, Builder, E, Pred, St, TargetLV, Val);
+}
+
 // End-of-path.
 
 void CFRefCount::EvalEndPath(GRExprEngine& Engine,

Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=49811&r1=49810&r2=49811&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Wed Apr 16 15:40:59 2008
@@ -709,20 +709,23 @@
 }
 
 void GRExprEngine::VisitStore(NodeSet& Dst, Expr* E, NodeTy* Pred,
-                              ValueState* St, LVal TargetLV, RVal Val) {
+                              ValueState* St, RVal TargetLV, RVal Val) {
   
   assert (Builder && "GRStmtNodeBuilder must be defined.");
   
   unsigned size = Dst.size();  
   SaveAndRestore<bool> OldSink(Builder->BuildSinks);
   
+  assert (!TargetLV.isUndef());
+  
   EvalStore(Dst, E, Pred, St, TargetLV, Val);
   
   // Handle the case where no nodes where generated.  Auto-generate that
   // contains the updated state if we aren't generating sinks.
   
   if (!Builder->BuildSinks && Dst.size() == size)
-    MakeNode(Dst, E, Pred, SetRVal(St, TargetLV, Val));    
+    TF->GRTransferFuncs::EvalStore(Dst, *this, *Builder, E, Pred, St,
+                                   TargetLV, Val);
 }
 
 //===----------------------------------------------------------------------===//
@@ -1643,21 +1646,12 @@
                      : cast<RVal>(nonlval::SymbolVal(Sym));            
           }
           
-          // Even if the LHS evaluates to an unknown L-Value, the entire
-          // expression still evaluates to the RHS.
-          
-          if (LeftV.isUnknown()) {
-            St = SetRVal(St, B, RightV);
-            break;
-          }
-          
           // Simulate the effects of a "store":  bind the value of the RHS
           // to the L-Value represented by the LHS.
 
           VisitStore(Dst, B, N2, SetRVal(St, B, RightV),
-                    cast<LVal>(LeftV), RightV);
+                     LeftV, RightV);
           
-//          St = SetRVal(SetRVal(St, B, RightV), cast<LVal>(LeftV), RightV);
           continue;
         }
 

Modified: cfe/trunk/lib/Analysis/GRTransferFuncs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRTransferFuncs.cpp?rev=49811&r1=49810&r2=49811&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRTransferFuncs.cpp (original)
+++ cfe/trunk/lib/Analysis/GRTransferFuncs.cpp Wed Apr 16 15:40:59 2008
@@ -13,7 +13,27 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
+#include "clang/Analysis/PathSensitive/GRExprEngine.h"
 
 using namespace clang;
 
 void GRTransferFuncs::RegisterChecks(GRExprEngine& Eng) {}
+
+void GRTransferFuncs::EvalStore(ExplodedNodeSet<ValueState>& Dst,
+                                GRExprEngine& Eng,
+                                GRStmtNodeBuilder<ValueState>& Builder,
+                                Expr* E, ExplodedNode<ValueState>* Pred,
+                                ValueState* St, RVal TargetLV, RVal Val) {
+  
+  // This code basically matches the "safety-net" logic of GRExprEngine:
+  //  bind Val to TargetLV, and create a new node.  We replicate it here
+  //  because subclasses of GRTransferFuncs may wish to call it.
+
+  assert (!TargetLV.isUndef());
+  
+  if (TargetLV.isUnknown())
+    Builder.MakeNode(Dst, E, Pred, St);
+  else
+    Builder.MakeNode(Dst, E, Pred,
+                Eng.getStateManager().SetRVal(St, cast<LVal>(TargetLV), Val));    
+}





More information about the cfe-commits mailing list