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

Ted Kremenek kremenek at apple.com
Fri Nov 14 16:20:06 PST 2008


Author: kremenek
Date: Fri Nov 14 18:20:05 2008
New Revision: 59335

URL: http://llvm.org/viewvc/llvm-project?rev=59335&view=rev
Log:
Implement FIXME in GRExprEngine::VisitUnaryOperator() to handle implicit conversions caused by the '!' operator.  This required adding some logic to GRSimpleVals to reason about nonloc::LocAsInteger SVals.  This code appears to work fine, but it should eventually be cleaned up.

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
    cfe/trunk/lib/Analysis/GRExprEngine.cpp
    cfe/trunk/lib/Analysis/GRSimpleVals.cpp
    cfe/trunk/lib/Analysis/GRSimpleVals.h
    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=59335&r1=59334&r2=59335&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Fri Nov 14 18:20:05 2008
@@ -592,12 +592,12 @@
   }
   
   SVal EvalBinOp(BinaryOperator::Opcode Op, NonLoc L, NonLoc R) {
-    return R.isValid() ? getTF().DetermEvalBinOpNN(getStateManager(), Op, L, R)
+    return R.isValid() ? getTF().DetermEvalBinOpNN(*this, Op, L, R)
                        : R;
   }
 
   SVal EvalBinOp(BinaryOperator::Opcode Op, NonLoc L, SVal R) {
-    return R.isValid() ? getTF().DetermEvalBinOpNN(getStateManager(), Op, L,
+    return R.isValid() ? getTF().DetermEvalBinOpNN(*this, Op, L,
                                                    cast<NonLoc>(R)) : R;
   }
   
@@ -634,7 +634,7 @@
                                cast<NonLoc>(L));
     }
     else
-      return getTF().DetermEvalBinOpNN(getStateManager(), Op, cast<NonLoc>(L),
+      return getTF().DetermEvalBinOpNN(*this, Op, cast<NonLoc>(L),
                                        cast<NonLoc>(R));
   }
   

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=59335&r1=59334&r2=59335&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h Fri Nov 14 18:20:05 2008
@@ -32,7 +32,7 @@
 protected:
   
   
-  virtual SVal DetermEvalBinOpNN(GRStateManager& StateMgr,
+  virtual SVal DetermEvalBinOpNN(GRExprEngine& Eng,
                                  BinaryOperator::Opcode Op,
                                  NonLoc L, NonLoc R) {
     return UnknownVal();
@@ -58,7 +58,9 @@
   virtual SVal EvalComplement(GRExprEngine& Engine, NonLoc X) = 0;
 
   // Binary Operators.
-  virtual void EvalBinOpNN(GRStateSet& OStates, GRStateManager& StateMgr,
+  // FIXME: We're moving back towards using GREXprEngine directly.  No need
+  // for OStates
+  virtual void EvalBinOpNN(GRStateSet& OStates, GRExprEngine& Eng,
                            const GRState* St, Expr* Ex,
                            BinaryOperator::Opcode Op, NonLoc L, NonLoc R);
   

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

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Fri Nov 14 18:20:05 2008
@@ -2044,10 +2044,16 @@
         // Get the value of the subexpression.
         SVal V = GetSVal(St, Ex);
 
-        // Perform promotions.
-        // FIXME: This is the right thing to do, but it currently breaks
-        //  a bunch of tests.
-        // V = EvalCast(V, U->getType()); 
+        if (V.isUnknownOrUndef()) {
+          MakeNode(Dst, U, *I, BindExpr(St, U, V));
+          continue;
+        }
+        
+        QualType DstT = getContext().getCanonicalType(U->getType());
+        QualType SrcT = getContext().getCanonicalType(Ex->getType());
+        
+        if (DstT != SrcT) // Perform promotions.
+          V = EvalCast(V, DstT); 
         
         if (V.isUnknownOrUndef()) {
           MakeNode(Dst, U, *I, BindExpr(St, U, V));
@@ -2551,7 +2557,7 @@
                              NonLoc L, NonLoc R) {
   
   GRStateSet::AutoPopulate AP(OStates, St);
-  if (R.isValid()) getTF().EvalBinOpNN(OStates, StateMgr, St, Ex, Op, L, R);
+  if (R.isValid()) getTF().EvalBinOpNN(OStates, *this, St, Ex, Op, L, R);
 }
 
 //===----------------------------------------------------------------------===//

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

==============================================================================
--- cfe/trunk/lib/Analysis/GRSimpleVals.cpp (original)
+++ cfe/trunk/lib/Analysis/GRSimpleVals.cpp Fri Nov 14 18:20:05 2008
@@ -69,20 +69,21 @@
   //   can be introduced by the frontend for corner cases, e.g
   //   casting from va_list* to __builtin_va_list&.
   //
+  assert (!X.isUnknownOrUndef());
+  
   if (Loc::IsLocType(T) || T->isReferenceType())
     return X;
   
   assert (T->isIntegerType());
-  
-  if (!isa<loc::ConcreteInt>(X))
-    return UnknownVal();
-  
   BasicValueFactory& BasicVals = Eng.getBasicVals();
+  unsigned BitWidth = Eng.getContext().getTypeSize(T);
+
+  if (!isa<loc::ConcreteInt>(X))
+    return nonloc::LocAsInteger::Make(BasicVals, X, BitWidth);
   
   llvm::APSInt V = cast<loc::ConcreteInt>(X).getValue();
   V.setIsUnsigned(T->isUnsignedIntegerType() || Loc::IsLocType(T));
-  V.extOrTrunc(Eng.getContext().getTypeSize(T));
-
+  V.extOrTrunc(BitWidth);
   return nonloc::ConcreteInt(BasicVals.getValue(V));
 }
 
@@ -123,11 +124,11 @@
   (unsigned char) BinaryOperator::EQ   /* NE => EQ */
 };
 
-SVal GRSimpleVals::DetermEvalBinOpNN(GRStateManager& StateMgr,
+SVal GRSimpleVals::DetermEvalBinOpNN(GRExprEngine& Eng,
                                      BinaryOperator::Opcode Op,
                                      NonLoc L, NonLoc R)  {
 
-  BasicValueFactory& BasicVals = StateMgr.getBasicVals();
+  BasicValueFactory& BasicVals = Eng.getBasicVals();
   unsigned subkind = L.getSubKind();
   
   while (1) {
@@ -136,6 +137,37 @@
       default:
         return UnknownVal();
         
+      case nonloc::LocAsIntegerKind: {
+        Loc LL = cast<nonloc::LocAsInteger>(L).getLoc();        
+        
+        switch (R.getSubKind()) {
+          case nonloc::LocAsIntegerKind:
+            return EvalBinOp(Eng, Op, LL,
+                             cast<nonloc::LocAsInteger>(R).getLoc());
+            
+          case nonloc::ConcreteIntKind: {
+            // Transform the integer into a location and compare.
+            ASTContext& Ctx = Eng.getContext();
+            llvm::APSInt V = cast<nonloc::ConcreteInt>(R).getValue();
+            V.setIsUnsigned(true);
+            V.extOrTrunc(Ctx.getTypeSize(Ctx.VoidPtrTy));
+            return EvalBinOp(Eng, Op, LL,
+                             loc::ConcreteInt(BasicVals.getValue(V)));
+          }
+          
+          default: 
+            switch (Op) {
+              case BinaryOperator::EQ:
+                return NonLoc::MakeIntTruthVal(BasicVals, false);
+              case BinaryOperator::NE:
+                return NonLoc::MakeIntTruthVal(BasicVals, true);
+              default:
+                // This case also handles pointer arithmetic.
+                return UnknownVal();
+            }
+        }
+      }
+        
       case nonloc::SymIntConstraintValKind: {
         
         // Logical not?        

Modified: cfe/trunk/lib/Analysis/GRSimpleVals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRSimpleVals.h?rev=59335&r1=59334&r2=59335&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRSimpleVals.h (original)
+++ cfe/trunk/lib/Analysis/GRSimpleVals.h Fri Nov 14 18:20:05 2008
@@ -27,7 +27,7 @@
 class GRSimpleVals : public GRTransferFuncs {
 protected:
   
-  virtual SVal DetermEvalBinOpNN(GRStateManager& StateMgr,
+  virtual SVal DetermEvalBinOpNN(GRExprEngine& Eng,
                                  BinaryOperator::Opcode Op,
                                  NonLoc L, NonLoc R);
   

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

==============================================================================
--- cfe/trunk/lib/Analysis/GRTransferFuncs.cpp (original)
+++ cfe/trunk/lib/Analysis/GRTransferFuncs.cpp Fri Nov 14 18:20:05 2008
@@ -39,10 +39,10 @@
 }
 
 void GRTransferFuncs::EvalBinOpNN(GRStateSet& OStates,
-                                  GRStateManager& StateMgr,
+                                  GRExprEngine& Eng,
                                   const GRState *St, Expr* Ex,
                                   BinaryOperator::Opcode Op,
                                   NonLoc L, NonLoc R) {
   
-  OStates.Add(StateMgr.BindExpr(St, Ex, DetermEvalBinOpNN(StateMgr, Op, L, R)));
+  OStates.Add(Eng.getStateManager().BindExpr(St, Ex, DetermEvalBinOpNN(Eng, Op, L, R)));
 }





More information about the cfe-commits mailing list