]> granicus.if.org Git - clang/commitdiff
Added more assertions and checks in transfer function logic to check for
authorTed Kremenek <kremenek@apple.com>
Mon, 18 Feb 2008 22:57:02 +0000 (22:57 +0000)
committerTed Kremenek <kremenek@apple.com>
Mon, 18 Feb 2008 22:57:02 +0000 (22:57 +0000)
UninitializedVals and UnknownVals.

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

Analysis/GRExprEngine.cpp
Analysis/GRSimpleVals.cpp
Analysis/ValueState.cpp
include/clang/Analysis/PathSensitive/GRExprEngine.h

index 4bcdd5fb70fd696487a45beafa39222b42557100..d709eff99fd3cac3d07c8f9ede065d914599bdbc 100644 (file)
@@ -209,7 +209,8 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) {
   typedef SwitchNodeBuilder::iterator iterator;
   
   StateTy St = builder.getState();  
-  NonLValue CondV = cast<NonLValue>(GetValue(St, builder.getCondition()));
+  Expr* CondE = builder.getCondition();
+  NonLValue CondV = cast<NonLValue>(GetValue(St, CondE));
 
   if (isa<UninitializedVal>(CondV)) {
     NodeTy* N = builder.generateDefaultCaseNode(St, true);
@@ -221,7 +222,10 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) {
   
   // While most of this can be assumed (such as the signedness), having it
   // just computed makes sure everything makes the same assumptions end-to-end.
-  unsigned bits = getContext().getTypeSize(getContext().IntTy,SourceLocation());
+  
+  unsigned bits = getContext().getTypeSize(CondE->getType(),
+                                           CondE->getExprLoc());
+
   APSInt V1(bits, false);
   APSInt V2 = V1;
   
@@ -258,7 +262,7 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) {
       NonLValue Res = EvalBinaryOp(ValMgr, BinaryOperator::EQ, CondV, CaseVal);
       
       // Now "assume" that the case matches.
-      bool isFeasible;
+      bool isFeasible = false;
       
       StateTy StNew = Assume(St, Res, true, isFeasible);
       
@@ -588,7 +592,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U,
         // FIXME: Stop when dereferencing an uninitialized value.
         // FIXME: Bifurcate when dereferencing a symbolic with no constraints?
         
-        const RValue& V = GetValue(St, U->getSubExpr());
+        const RValue& V = GetValue(St, U->getSubExpr());        
         const LValue& L1 = cast<LValue>(V);
         
         // After a dereference, one of two possible situations arise:
@@ -608,6 +612,9 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U,
                                       GetValue(StNotNull, L1, &T)));
         }
         
+        if (V.isUnknown())
+          return;
+        
         bool isFeasibleNull;
         
         // "Assume" that the pointer is NULL.
@@ -868,8 +875,15 @@ void GRExprEngine::Visit(Stmt* S, GRExprEngine::NodeTy* Pred,
 //===----------------------------------------------------------------------===//
 
 GRExprEngine::StateTy GRExprEngine::Assume(StateTy St, LValue Cond,
-                                         bool Assumption, 
-                                         bool& isFeasible) {    
+                                           bool Assumption, 
+                                           bool& isFeasible) {    
+  
+  assert (!isa<UninitializedVal>(Cond));
+
+  if (isa<UnknownVal>(Cond)) {
+    isFeasible = true;
+    return St;  
+  }
   
   switch (Cond.getSubKind()) {
     default:
@@ -901,6 +915,13 @@ GRExprEngine::StateTy GRExprEngine::Assume(StateTy St, NonLValue Cond,
                                          bool Assumption, 
                                          bool& isFeasible) {
   
+  assert (!isa<UninitializedVal>(Cond));
+  
+  if (isa<UnknownVal>(Cond)) {
+    isFeasible = true;
+    return St;  
+  }
+  
   switch (Cond.getSubKind()) {
     default:
       assert (false && "'Assume' not implemented for this NonLValue.");
@@ -936,7 +957,7 @@ GRExprEngine::StateTy GRExprEngine::Assume(StateTy St, NonLValue Cond,
 GRExprEngine::StateTy
 GRExprEngine::AssumeSymNE(StateTy St, SymbolID sym,
                          const llvm::APSInt& V, bool& isFeasible) {
-
+  
   // First, determine if sym == X, where X != V.
   if (const llvm::APSInt* X = St.getSymVal(sym)) {
     isFeasible = *X != V;
index 58f0729a70182d11f1a0820c4db0328e527f394b..87b39b70c53da37d0ec1b029d00cfe0bf415883b 100644 (file)
@@ -31,7 +31,7 @@ namespace clang {
     CheckerState->setTransferFunctions(GRSV);
     
     // Execute the worklist algorithm.
-    Engine.ExecuteWorkList(200);
+    Engine.ExecuteWorkList(10000);
     
     // Look for explicit-Null dereferences and warn about them.
     for (GRExprEngine::null_iterator I=CheckerState->null_begin(),
@@ -57,6 +57,8 @@ namespace clang {
 RValue GRSimpleVals::EvalCast(ValueManager& ValMgr, NonLValue X,
                               Expr* CastExpr) {
   
+  assert (!isa<UnknownVal>(X) && !isa<UninitializedVal>(X));
+  
   if (!isa<nonlval::ConcreteInt>(X))
     return UnknownVal();
   
@@ -74,6 +76,8 @@ RValue GRSimpleVals::EvalCast(ValueManager& ValMgr, NonLValue X,
 // Casts.
 
 RValue GRSimpleVals::EvalCast(ValueManager& ValMgr, LValue X, Expr* CastExpr) {
+  
+  assert (!isa<UnknownVal>(X) && !isa<UninitializedVal>(X));
 
   if (CastExpr->getType()->isPointerType())
     return X;
@@ -96,6 +100,8 @@ RValue GRSimpleVals::EvalCast(ValueManager& ValMgr, LValue X, Expr* CastExpr) {
 NonLValue GRSimpleVals::EvalMinus(ValueManager& ValMgr, UnaryOperator* U,
                                   NonLValue X) {
   
+  assert (!isa<UnknownVal>(X) && !isa<UninitializedVal>(X));
+  
   switch (X.getSubKind()) {
     case nonlval::ConcreteIntKind:
       return cast<nonlval::ConcreteInt>(X).EvalMinus(ValMgr, U);
@@ -105,6 +111,9 @@ NonLValue GRSimpleVals::EvalMinus(ValueManager& ValMgr, UnaryOperator* U,
 }
 
 NonLValue GRSimpleVals::EvalComplement(ValueManager& ValMgr, NonLValue X) {
+
+  assert (!isa<UnknownVal>(X) && !isa<UninitializedVal>(X));
+  
   switch (X.getSubKind()) {
     case nonlval::ConcreteIntKind:
       return cast<nonlval::ConcreteInt>(X).EvalComplement(ValMgr);
@@ -119,11 +128,8 @@ NonLValue GRSimpleVals::EvalBinaryOp(ValueManager& ValMgr,
                                      BinaryOperator::Opcode Op,
                                      NonLValue LHS, NonLValue RHS)  {
   
-  if (isa<UnknownVal>(LHS) || isa<UnknownVal>(RHS))
-    return cast<NonLValue>(UnknownVal());
-  
-  if (isa<UninitializedVal>(LHS) || isa<UninitializedVal>(RHS))
-    return cast<NonLValue>(UninitializedVal());
+  assert (!isa<UnknownVal>(LHS) && !isa<UninitializedVal>(LHS));
+  assert (!isa<UnknownVal>(RHS) && !isa<UninitializedVal>(RHS));
   
   while(1) {
     
@@ -169,6 +175,9 @@ RValue GRSimpleVals::EvalBinaryOp(ValueManager& ValMgr,
                                   BinaryOperator::Opcode Op,
                                   LValue LHS, LValue RHS) {
   
+  assert (!isa<UnknownVal>(LHS) && !isa<UninitializedVal>(LHS));
+  assert (!isa<UnknownVal>(RHS) && !isa<UninitializedVal>(RHS));
+  
   switch (Op) {
     default:
       return UnknownVal();
@@ -186,6 +195,10 @@ RValue GRSimpleVals::EvalBinaryOp(ValueManager& ValMgr,
 LValue GRSimpleVals::EvalBinaryOp(ValueManager& ValMgr,
                                   BinaryOperator::Opcode Op,
                                   LValue LHS, NonLValue RHS) {
+  
+  assert (!isa<UnknownVal>(LHS) && !isa<UninitializedVal>(LHS));
+  assert (!isa<UnknownVal>(RHS) && !isa<UninitializedVal>(RHS));
+  
   return cast<LValue>(UnknownVal());
 }
 
@@ -194,6 +207,9 @@ LValue GRSimpleVals::EvalBinaryOp(ValueManager& ValMgr,
 
 NonLValue GRSimpleVals::EvalEQ(ValueManager& ValMgr, LValue LHS, LValue RHS) {
   
+  assert (!isa<UnknownVal>(LHS) && !isa<UninitializedVal>(LHS));
+  assert (!isa<UnknownVal>(RHS) && !isa<UninitializedVal>(RHS));
+  
   switch (LHS.getSubKind()) {
     default:
       assert(false && "EQ not implemented for this LValue.");
@@ -249,6 +265,9 @@ NonLValue GRSimpleVals::EvalEQ(ValueManager& ValMgr, LValue LHS, LValue RHS) {
 }
 
 NonLValue GRSimpleVals::EvalNE(ValueManager& ValMgr, LValue LHS, LValue RHS) {
+  
+  assert (!isa<UnknownVal>(LHS) && !isa<UninitializedVal>(LHS));
+  assert (!isa<UnknownVal>(RHS) && !isa<UninitializedVal>(RHS));
 
   switch (LHS.getSubKind()) {
     default:
index 9b2ed9686a9c720d0435c3d1f1288d799aebe28d..016b070547a15ff8c6a77bdf12ed4b774d9dd0d9 100644 (file)
@@ -129,6 +129,8 @@ RValue ValueStateManager::GetValue(ValueState St, const LValue& LV,
   if (isa<UnknownVal>(LV))
     return UnknownVal();
   
+  assert (!isa<UninitializedVal>(LV));
+  
   switch (LV.getSubKind()) {
     case lval::DeclValKind: {
       ValueState::VarBindingsTy::TreeTy* T =
@@ -327,6 +329,9 @@ ValueStateManager::SetValue(ValueState St, Expr* E, bool isBlkExpr,
 ValueState
 ValueStateManager::SetValue(ValueState St, const LValue& LV, const RValue& V) {
   
+  assert (!isa<UnknownVal>(LV));
+  assert (!isa<UninitializedVal>(LV));
+    
   switch (LV.getSubKind()) {
     case lval::DeclValKind:        
       return V.isKnown()   // FIXME: Have DeclVal only contain VarDecl
index a52a776a1d34b1a8d00cd5e430562f023034ab98..ff9c26cf7c6c63655e2d8ef9ff9fa09fe6791526 100644 (file)
@@ -308,36 +308,73 @@ public:
   void VisitUnaryOperator(UnaryOperator* B, NodeTy* Pred, NodeSet& Dst);
   
   
-  inline RValue EvalCast(ValueManager& ValMgr, RValue R, Expr* CastExpr) {
-    return TF->EvalCast(ValMgr, R, CastExpr);
+  inline RValue EvalCast(ValueManager& ValMgr, RValue X, Expr* CastExpr) {
+    if (isa<UnknownVal>(X) || isa<UninitializedVal>(X))
+      return X;    
+    
+    return TF->EvalCast(ValMgr, X, CastExpr);
   }
   
   inline NonLValue EvalMinus(ValueManager& ValMgr, UnaryOperator* U,
                              NonLValue X) {
+    if (isa<UnknownVal>(X) || isa<UninitializedVal>(X))
+      return X;    
+    
     return TF->EvalMinus(ValMgr, U, X);    
   }
   
   inline NonLValue EvalComplement(ValueManager& ValMgr, NonLValue X) {
+    if (isa<UnknownVal>(X) || isa<UninitializedVal>(X))
+      return X;    
+
     return TF->EvalComplement(ValMgr, X);
   }
   
   inline NonLValue EvalBinaryOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
                                 NonLValue LHS, NonLValue RHS) {
+    
+    if (isa<UninitializedVal>(LHS) || isa<UninitializedVal>(RHS))
+      return cast<NonLValue>(UninitializedVal());
+    
+    if (isa<UnknownVal>(LHS) || isa<UnknownVal>(RHS))
+      return cast<NonLValue>(UnknownVal());
+    
     return TF->EvalBinaryOp(ValMgr, Op, LHS, RHS);
   }    
   
   inline RValue EvalBinaryOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
                              LValue LHS, LValue RHS) {
+    
+    if (isa<UninitializedVal>(LHS) || isa<UninitializedVal>(RHS))
+      return UninitializedVal();
+    
+    if (isa<UnknownVal>(LHS) || isa<UnknownVal>(RHS))
+      return UnknownVal();
+    
     return TF->EvalBinaryOp(ValMgr, Op, LHS, RHS);
   }
   
   inline RValue EvalBinaryOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
                              LValue LHS, NonLValue RHS) {
+    
+    if (isa<UninitializedVal>(LHS) || isa<UninitializedVal>(RHS))
+      return UninitializedVal();
+    
+    if (isa<UnknownVal>(LHS) || isa<UnknownVal>(RHS))
+      return UnknownVal();
+    
     return TF->EvalBinaryOp(ValMgr, Op, LHS, RHS);
   }
   
   inline RValue EvalBinaryOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
                              RValue LHS, RValue RHS) {
+    
+    if (isa<UninitializedVal>(LHS) || isa<UninitializedVal>(RHS))
+      return UninitializedVal();
+    
+    if (isa<UnknownVal>(LHS) || isa<UnknownVal>(RHS))
+      return UnknownVal();
+    
     return TF->EvalBinaryOp(ValMgr, Op, LHS, RHS);
   }
 };