[cfe-commits] r47125 - in /cfe/trunk: Analysis/GRExprEngine.cpp Analysis/GRSimpleVals.cpp Analysis/GRSimpleVals.h Analysis/GRTransferFuncs.cpp Analysis/RValues.cpp include/clang/Analysis/PathSensitive/GRTransferFuncs.h include/clang/Analysis/PathSensitive/RValues.h

Ted Kremenek kremenek at apple.com
Thu Feb 14 10:28:24 PST 2008


Author: kremenek
Date: Thu Feb 14 12:28:23 2008
New Revision: 47125

URL: http://llvm.org/viewvc/llvm-project?rev=47125&view=rev
Log:
Started partitioning of transfer function logic (and thus the policy behind 
these operations) into GRTransferFuncs and its subclasses.  Originally all
of this logic was handled by the class RValue, but in reality different
analyses will want more flexibility on how they evaluate different values.

Transfer functions migrated so far: "Cast"

Added:
    cfe/trunk/Analysis/GRSimpleVals.cpp
    cfe/trunk/Analysis/GRSimpleVals.h
    cfe/trunk/Analysis/GRTransferFuncs.cpp
    cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
Modified:
    cfe/trunk/Analysis/GRExprEngine.cpp
    cfe/trunk/Analysis/RValues.cpp
    cfe/trunk/include/clang/Analysis/PathSensitive/RValues.h

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

==============================================================================
--- cfe/trunk/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/Analysis/GRExprEngine.cpp Thu Feb 14 12:28:23 2008
@@ -18,6 +18,9 @@
 #include "ValueState.h"
 
 #include "clang/Analysis/PathSensitive/GRCoreEngine.h"
+#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
+#include "GRSimpleVals.h"
+
 #include "clang/AST/Expr.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/Analysis/Analyses/LiveVariables.h"
@@ -73,7 +76,6 @@
   typedef GRIndirectGotoNodeBuilder<GRExprEngine> IndirectGotoNodeBuilder;
   typedef GRSwitchNodeBuilder<GRExprEngine> SwitchNodeBuilder;
   
-  
   class NodeSet {
     typedef llvm::SmallVector<NodeTy*,3> ImplTy;
     ImplTy Impl;
@@ -115,6 +117,10 @@
   /// ValueMgr - Object that manages the data for all created RValues.
   ValueManager& ValMgr;
   
+  /// TF - Object that represents a bundle of transfer functions
+  ///  for manipulating and creating RValues.
+  GRTransferFuncs& TF;
+  
   /// SymMgr - Object that manages the symbol information.
   SymbolManager& SymMgr;
   
@@ -139,10 +145,12 @@
   bool StateCleaned;
   
 public:
-  GRExprEngine(GraphTy& g) : G(g), Liveness(G.getCFG(), G.getFunctionDecl()),
+  GRExprEngine(GraphTy& g) : 
+      G(g), Liveness(G.getCFG(), G.getFunctionDecl()),
       Builder(NULL),
       StateMgr(G.getContext(), G.getAllocator()),
       ValMgr(StateMgr.getValueManager()),
+      TF(*(new GRSimpleVals())), // FIXME.
       SymMgr(StateMgr.getSymbolManager()),
       StmtEntryNode(NULL), CurrentStmt(NULL) {
     
@@ -312,6 +320,11 @@
   /// VisitUnaryOperator - Transfer function logic for unary operators.
   void VisitUnaryOperator(UnaryOperator* B, NodeTy* Pred, NodeSet& Dst);
   
+  
+  inline RValue EvalCast(ValueManager& ValMgr, RValue R, Expr* CastExpr) {
+    return TF.EvalCast(ValMgr, R, CastExpr);
+  }
+  
 };
 } // end anonymous namespace
 
@@ -702,7 +715,7 @@
     NodeTy* N = *I1;
     StateTy St = N->getState();
     const RValue& V = GetValue(St, E);
-    Nodify(Dst, CastE, N, SetValue(St, CastE, V.EvalCast(ValMgr, CastE)));
+    Nodify(Dst, CastE, N, SetValue(St, CastE, EvalCast(ValMgr, V, CastE)));
   }
 }
 
@@ -1511,10 +1524,13 @@
                     Diagnostic& Diag) {
   
   GRCoreEngine<GRExprEngine> Engine(cfg, FD, Ctx);
+  GRExprEngine* CheckerState = &Engine.getCheckerState();
+  
+  // Execute the worklist algorithm.
   Engine.ExecuteWorkList();
   
   // Look for explicit-Null dereferences and warn about them.
-  GRExprEngine* CheckerState = &Engine.getCheckerState();
+
   
   for (GRExprEngine::null_iterator I=CheckerState->null_begin(),
                                   E=CheckerState->null_end(); I!=E; ++I) {

Added: cfe/trunk/Analysis/GRSimpleVals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRSimpleVals.cpp?rev=47125&view=auto

==============================================================================
--- cfe/trunk/Analysis/GRSimpleVals.cpp (added)
+++ cfe/trunk/Analysis/GRSimpleVals.cpp Thu Feb 14 12:28:23 2008
@@ -0,0 +1,59 @@
+// GRSimpleVals.cpp - Transfer functions for tracking simple values -*- C++ -*--
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This files defines GRSimpleVals, a sub-class of GRTransferFuncs that
+//  provides transfer functions for performing simple value tracking with
+//  limited support for symbolics.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRSimpleVals.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Transfer function for Casts.
+//===----------------------------------------------------------------------===//
+
+RValue GRSimpleVals::EvalCast(ValueManager& ValMgr, NonLValue X,
+                              Expr* CastExpr) {
+  
+  if (!isa<nonlval::ConcreteInt>(X))
+    return UnknownVal();
+  
+  llvm::APSInt V = cast<nonlval::ConcreteInt>(X).getValue();
+  QualType T = CastExpr->getType();
+  V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
+  V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
+  
+  if (CastExpr->getType()->isPointerType())
+    return lval::ConcreteInt(ValMgr.getValue(V));
+  else
+    return nonlval::ConcreteInt(ValMgr.getValue(V));
+}
+
+// Casts.
+
+RValue GRSimpleVals::EvalCast(ValueManager& ValMgr, LValue X, Expr* CastExpr) {
+
+  if (CastExpr->getType()->isPointerType())
+    return X;
+  
+  assert (CastExpr->getType()->isIntegerType());
+  
+  if (!isa<lval::ConcreteInt>(X))
+    return UnknownVal();
+  
+  llvm::APSInt V = cast<lval::ConcreteInt>(X).getValue();
+  QualType T = CastExpr->getType();
+  V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
+  V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
+
+  return nonlval::ConcreteInt(ValMgr.getValue(V));
+}
\ No newline at end of file

Added: cfe/trunk/Analysis/GRSimpleVals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRSimpleVals.h?rev=47125&view=auto

==============================================================================
--- cfe/trunk/Analysis/GRSimpleVals.h (added)
+++ cfe/trunk/Analysis/GRSimpleVals.h Thu Feb 14 12:28:23 2008
@@ -0,0 +1,35 @@
+// GRSimpleVals.h - Transfer functions for tracking simple values -*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This files defines GRSimpleVals, a sub-class of GRTransferFuncs that
+//  provides transfer functions for performing simple value tracking with
+//  limited support for symbolics.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GRSIMPLEVALS
+#define LLVM_CLANG_ANALYSIS_GRSIMPLEVALS
+
+#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
+
+namespace clang {
+  
+class GRSimpleVals : public GRTransferFuncs {
+public:
+  GRSimpleVals() {}
+  virtual ~GRSimpleVals() {}
+  
+  virtual RValue EvalCast(ValueManager& ValMgr, NonLValue V, Expr* CastExpr);
+  virtual RValue EvalCast(ValueManager& ValMgr, LValue V, Expr* CastExpr);
+};
+  
+  
+} // end clang namespace
+
+#endif

Added: cfe/trunk/Analysis/GRTransferFuncs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRTransferFuncs.cpp?rev=47125&view=auto

==============================================================================
--- cfe/trunk/Analysis/GRTransferFuncs.cpp (added)
+++ cfe/trunk/Analysis/GRTransferFuncs.cpp Thu Feb 14 12:28:23 2008
@@ -0,0 +1,41 @@
+//== GRTransferFuncs.cpp - Path-Sens. Transfer Functions Interface -*- C++ -*--=
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This files defines GRTransferFuncs, which provides a base-class that
+//  defines an interface for transfer functions used by GRExprEngine.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Transfer function for Casts.
+//===----------------------------------------------------------------------===//
+
+RValue GRTransferFuncs::EvalCast(ValueManager& ValMgr, RValue X,
+                                 Expr* CastExpr) {
+  
+  switch (X.getBaseKind()) {
+    default:
+      assert(false && "Invalid RValue."); break;
+
+    case RValue::LValueKind: 
+      return EvalCast(ValMgr, cast<LValue>(X), CastExpr);
+
+    case RValue::NonLValueKind:
+      return EvalCast(ValMgr, cast<NonLValue>(X), CastExpr);
+    
+    case RValue::UninitializedKind:
+    case RValue::UnknownKind: break;
+  }
+  
+  return X;
+}

Modified: cfe/trunk/Analysis/RValues.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/RValues.cpp?rev=47125&r1=47124&r2=47125&view=diff

==============================================================================
--- cfe/trunk/Analysis/RValues.cpp (original)
+++ cfe/trunk/Analysis/RValues.cpp Thu Feb 14 12:28:23 2008
@@ -123,20 +123,7 @@
   return *C;
 }
 
-//===----------------------------------------------------------------------===//
-// Transfer function for Casts.
-//===----------------------------------------------------------------------===//
 
-RValue RValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
-  switch (getBaseKind()) {
-    default: assert(false && "Invalid RValue."); break;
-    case LValueKind: return cast<LValue>(this)->EvalCast(ValMgr, CastExpr);
-    case NonLValueKind: return cast<NonLValue>(this)->EvalCast(ValMgr, CastExpr);      
-    case UninitializedKind: case UnknownKind: break;
-  }
-  
-  return *this;
-}
  
 
 //===----------------------------------------------------------------------===//
@@ -270,23 +257,6 @@
   return ValMgr.getValue(~getValue()); 
 }
 
-  // Casts.
-
-RValue NonLValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
-  if (!isa<nonlval::ConcreteInt>(this))
-    return UnknownVal();
-  
-  APSInt V = cast<nonlval::ConcreteInt>(this)->getValue();
-  QualType T = CastExpr->getType();
-  V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
-  V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
-  
-  if (CastExpr->getType()->isPointerType())
-    return lval::ConcreteInt(ValMgr.getValue(V));
-  else
-    return nonlval::ConcreteInt(ValMgr.getValue(V));
-}
-
   // Unary Minus.
 
 NonLValue NonLValue::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
@@ -445,23 +415,7 @@
   return NonLValue::GetIntTruthValue(ValMgr, true);
 }
 
-  // Casts.
 
-RValue LValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
-  if (CastExpr->getType()->isPointerType())
-    return *this;
-  
-  assert (CastExpr->getType()->isIntegerType());
-  
-  if (!isa<lval::ConcreteInt>(*this))
-    return UnknownVal();
-  
-  APSInt V = cast<lval::ConcreteInt>(this)->getValue();
-  QualType T = CastExpr->getType();
-  V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
-  V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
-  return nonlval::ConcreteInt(ValMgr.getValue(V));
-}
 
 //===----------------------------------------------------------------------===//
 // Utility methods for constructing Non-LValues.

Added: cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h?rev=47125&view=auto

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h (added)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h Thu Feb 14 12:28:23 2008
@@ -0,0 +1,37 @@
+//== GRTransferFuncs.h - Path-Sens. Transfer Functions Interface -*- C++ -*--=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This files defines GRTransferFuncs, which provides a base-class that
+//  defines an interface for transfer functions used by GRExprEngine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GRTF
+#define LLVM_CLANG_ANALYSIS_GRTF
+
+#include "clang/Analysis/PathSensitive/RValues.h"
+
+namespace clang {
+  
+class GRTransferFuncs {
+public:
+  GRTransferFuncs() {}
+  virtual ~GRTransferFuncs() {}
+  
+  RValue EvalCast(ValueManager& ValMgr, RValue V, Expr* CastExpr);
+  virtual RValue EvalCast(ValueManager& ValMgr, NonLValue V, Expr* CastExpr) =0;
+  virtual RValue EvalCast(ValueManager& ValMgr, LValue V, Expr* CastExpr) = 0;
+
+  
+  
+};
+  
+} // end clang namespace
+
+#endif

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

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/RValues.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/RValues.h Thu Feb 14 12:28:23 2008
@@ -270,9 +270,6 @@
   
   /// BufferTy - A temporary buffer to hold a set of RValues.
   typedef llvm::SmallVector<RValue,5> BufferTy;
-
-  
-  RValue EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
   
   unsigned getRawKind() const { return Kind; }
   BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
@@ -329,7 +326,6 @@
                                BinaryOperator::Opcode Op,
                                const NonLValue& RHS) const;
 
-  RValue EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
   NonLValue EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const;
   NonLValue EvalComplement(ValueManager& ValMgr) const;
   
@@ -361,9 +357,7 @@
 
   RValue EvalBinaryOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
                             const LValue& RHS) const;
-  
-  RValue EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
-  
+    
   static LValue GetValue(AddrLabelExpr* E);
   
   // Implement isa<T> support.





More information about the cfe-commits mailing list