]> granicus.if.org Git - clang/commitdiff
Simplified and generalized transfer function logic for casts, allowing
authorTed Kremenek <kremenek@apple.com>
Thu, 21 Feb 2008 18:43:30 +0000 (18:43 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 21 Feb 2008 18:43:30 +0000 (18:43 +0000)
the transfer function to be invoked without an Expr* for the Cast operation.

Added implicit promotions to the transfer function logic for compound
assignments.

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

Analysis/GRExprEngine.cpp
Analysis/GRSimpleVals.cpp
Analysis/GRSimpleVals.h
Analysis/GRTransferFuncs.cpp [deleted file]
include/clang/Analysis/PathSensitive/GRExprEngine.h
include/clang/Analysis/PathSensitive/GRTransferFuncs.h

index 1ca37615d81bf08ae98f59a82a5cbd61e050595c..51b0a597eede004f2a41d829f2559da8bf88568b 100644 (file)
@@ -477,7 +477,7 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){
     NodeTy* N = *I1;
     StateTy St = N->getState();
     RVal V = GetRVal(St, Ex);
-    Nodify(Dst, CastE, N, SetRVal(St, CastE, EvalCast(ValMgr, V, CastE)));
+    Nodify(Dst, CastE, N, SetRVal(St, CastE, EvalCast(V, CastE->getType())));
   }
 }
 
@@ -520,14 +520,13 @@ void GRExprEngine::VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R,
 void GRExprEngine::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr* Ex,
                                               NodeTy* Pred,
                                               NodeSet& Dst) {
-  
-  assert (Ex->isSizeOf() && "AlignOf(Expr) not yet implemented.");
+
+  assert (Ex->isSizeOf() && "FIXME: AlignOf(Expr) not yet implemented.");
   
   // 6.5.3.4 sizeof: "The result type is an integer."
   
   QualType T = Ex->getArgumentType();
-  
-  // FIXME: Implement alignof
+
 
   // FIXME: Add support for VLAs.
   if (!T.getTypePtr()->isConstantSizeType())
@@ -942,7 +941,16 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
           else
             ((int&) Op) -= BinaryOperator::MulAssign;          
           
-          RVal Result = EvalBinOp(Op, V, RightV);
+          // Get the computation type.
+          QualType CTy = cast<CompoundAssignOperator>(B)->getComputationType();
+          
+          // Perform promotions.
+          V = EvalCast(V, CTy);
+          RightV = EvalCast(V, CTy);
+          
+          // Evaluate operands and promote to result type.
+          RVal Result = EvalCast(EvalBinOp(Op, V, RightV), B->getType());
+          
           St = SetRVal(SetRVal(St, B, Result), LeftLV, Result);
         }
       }
index 675882f42e09ad734d3d51dd9a272430c2993841..ed0706be892ba9d10a44b0663922a728db898854 100644 (file)
@@ -58,17 +58,16 @@ unsigned RunGRSimpleVals(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx,
 // Transfer function for Casts.
 //===----------------------------------------------------------------------===//
 
-RVal GRSimpleVals::EvalCast(ValueManager& ValMgr, NonLVal X, Expr* CastExpr) {
+RVal GRSimpleVals::EvalCast(ValueManager& ValMgr, NonLVal X, QualType T) {
   
   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()));
+  V.extOrTrunc(ValMgr.getContext().getTypeSize(T, SourceLocation()));
   
-  if (CastExpr->getType()->isPointerType())
+  if (T->isPointerType())
     return lval::ConcreteInt(ValMgr.getValue(V));
   else
     return nonlval::ConcreteInt(ValMgr.getValue(V));
@@ -76,20 +75,19 @@ RVal GRSimpleVals::EvalCast(ValueManager& ValMgr, NonLVal X, Expr* CastExpr) {
 
 // Casts.
 
-RVal GRSimpleVals::EvalCast(ValueManager& ValMgr, LVal X, Expr* CastExpr) {
+RVal GRSimpleVals::EvalCast(ValueManager& ValMgr, LVal X, QualType T) {
   
-  if (CastExpr->getType()->isPointerType())
+  if (T->isPointerType())
     return X;
   
-  assert (CastExpr->getType()->isIntegerType());
+  assert (T->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()));
+  V.extOrTrunc(ValMgr.getContext().getTypeSize(T, SourceLocation()));
 
   return nonlval::ConcreteInt(ValMgr.getValue(V));
 }
index 28286ec11f8292e7f9ba3861d73a04a839065dfb..870166e8f4b75849475a257d54880e4e17852c88 100644 (file)
@@ -28,8 +28,8 @@ public:
   
   // Casts.
   
-  virtual RVal EvalCast(ValueManager& ValMgr, NonLVal V, Expr* CastExpr);
-  virtual RVal EvalCast(ValueManager& ValMgr, LVal V, Expr* CastExpr);
+  virtual RVal EvalCast(ValueManager& ValMgr, NonLVal V, QualType CastT);
+  virtual RVal EvalCast(ValueManager& ValMgr, LVal V, QualType CastT);
   
   // Unary Operators.
   
diff --git a/Analysis/GRTransferFuncs.cpp b/Analysis/GRTransferFuncs.cpp
deleted file mode 100644 (file)
index 29d6216..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-//== 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.
-//===----------------------------------------------------------------------===//
-
-RVal GRTransferFuncs::EvalCast(ValueManager& ValMgr, RVal X, Expr* CastExpr) {
-  
-  switch (X.getBaseKind()) {
-      
-    default:
-      assert(false && "Invalid RVal."); break;
-
-    case RVal::LValKind: 
-      return EvalCast(ValMgr, cast<LVal>(X), CastExpr);
-
-    case RVal::NonLValKind:
-      return EvalCast(ValMgr, cast<NonLVal>(X), CastExpr);
-    
-    case RVal::UninitializedKind:
-    case RVal::UnknownKind: break;
-  }
-  
-  return X;
-}
index fbb0275dd4ef543083d41b9b27d81833a1624f9d..f83f3d3e5c4528ae8477151c93605acb93517872 100644 (file)
@@ -341,8 +341,14 @@ public:
   
   void VisitDeref(UnaryOperator* B, NodeTy* Pred, NodeSet& Dst);
   
-  RVal EvalCast(ValueManager& ValMgr, RVal X, Expr* CastExpr) {
-    return X.isValid() ? TF->EvalCast(ValMgr, X, CastExpr) : X;
+  RVal EvalCast(RVal X, QualType CastT) {
+    if (X.isUnknownOrUninit())
+      return X;
+    
+    if (isa<LVal>(X))
+      return TF->EvalCast(ValMgr, cast<LVal>(X), CastT);
+    else
+      return TF->EvalCast(ValMgr, cast<NonLVal>(X), CastT);
   }
   
   RVal EvalMinus(UnaryOperator* U, RVal X) {
index faa559ee58c9361e5252c35e3ad52ed438e4f0d8..2a8ec2b6f77c1794ea1863fa453d3e2701dc3e16 100644 (file)
@@ -26,9 +26,8 @@ public:
   
   // Casts.
   
-  RVal EvalCast(ValueManager& ValMgr, RVal V, Expr* CastExpr);
-  virtual RVal EvalCast(ValueManager& ValMgr, NonLVal V, Expr* CastExpr) =0;
-  virtual RVal EvalCast(ValueManager& ValMgr, LVal V, Expr* CastExpr) = 0;
+  virtual RVal EvalCast(ValueManager& ValMgr, NonLVal V, QualType CastT) =0;
+  virtual RVal EvalCast(ValueManager& ValMgr, LVal V, QualType CastT) = 0;
 
   // Unary Operators.