]> granicus.if.org Git - clang/commitdiff
Added special handling for UninitializedVals for the transfer function logic
authorTed Kremenek <kremenek@apple.com>
Tue, 19 Feb 2008 20:53:06 +0000 (20:53 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 19 Feb 2008 20:53:06 +0000 (20:53 +0000)
for pointer dereferences.

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

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

index d1a0d4c59b0094b1131fabd5b219a55d28715fa9..ef3664ef4314d08a976a24955b1addbc462be73b 100644 (file)
@@ -642,6 +642,17 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U,
         const RValue& V = GetValue(St, U->getSubExpr());        
         const LValue& L1 = cast<LValue>(V);
         
+        if (isa<UninitializedVal>(L1)) {
+          NodeTy* N = Builder->generateNode(U, St, N1);
+          
+          if (N) {
+            N->markAsSink();
+            UninitDeref.insert(N);            
+          }
+          
+          return;
+        }
+        
         // After a dereference, one of two possible situations arise:
         //  (1) A crash, because the pointer was NULL.
         //  (2) The pointer is not NULL, and the dereference works.
@@ -776,6 +787,11 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
             break;
           }
           
+          if (isa<UninitializedVal>(V2)) {
+            Nodify(Dst, B, N2, SetValue(SetValue(St, B, V2), L1, V2));
+            break;
+          }
+          
           RValue Result = cast<NonLValue>(UnknownVal());
           
           if (Op >= BinaryOperator::AndAssign)
@@ -1232,6 +1248,7 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :
     
     if (GraphPrintCheckerState->isImplicitNullDeref(N) ||
         GraphPrintCheckerState->isExplicitNullDeref(N) ||
+        GraphPrintCheckerState->isUninitDeref(N) ||
         GraphPrintCheckerState->isUninitStore(N) ||
         GraphPrintCheckerState->isUninitControlFlow(N))
       return "color=\"red\",style=\"filled\"";
@@ -1268,6 +1285,9 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :
         else if (GraphPrintCheckerState->isExplicitNullDeref(N)) {
           Out << "\\|Explicit-Null Dereference.\\l";
         }
+        else if (GraphPrintCheckerState->isUninitDeref(N)) {
+          Out << "\\|Dereference of uninitialied value.\\l";
+        }
         else if (GraphPrintCheckerState->isUninitStore(N)) {
           Out << "\\|Store to Uninitialized LValue.";
         }
index 4f9456d4e367a275611bd332027ba3c9fb398187..d4c9932c066ff7f96a246b9f864bb36e67460071 100644 (file)
@@ -121,9 +121,10 @@ protected:
   
   /// ImplicitNullDeref - Nodes in the ExplodedGraph that result from
   ///  taking a dereference on a symbolic pointer that may be NULL.
-  typedef llvm::SmallPtrSet<NodeTy*,5> NullDerefTy;
-  NullDerefTy ImplicitNullDeref;
-  NullDerefTy ExplicitNullDeref;
+  typedef llvm::SmallPtrSet<NodeTy*,5> BadDerefTy;
+  BadDerefTy ImplicitNullDeref;
+  BadDerefTy ExplicitNullDeref;
+  BadDerefTy UninitDeref;
   
   bool StateCleaned;
   
@@ -187,7 +188,11 @@ public:
     return N->isSink() && ExplicitNullDeref.count(const_cast<NodeTy*>(N)) != 0;
   }
   
-  typedef NullDerefTy::iterator null_iterator;
+  bool isUninitDeref(const NodeTy* N) const {
+    return N->isSink() && UninitDeref.count(const_cast<NodeTy*>(N)) != 0;
+  }
+  
+  typedef BadDerefTy::iterator null_iterator;
   null_iterator null_begin() { return ExplicitNullDeref.begin(); }
   null_iterator null_end() { return ExplicitNullDeref.end(); }