[cfe-commits] r47293 - in /cfe/trunk: Analysis/GRExprEngine.cpp Analysis/GRSimpleVals.cpp Analysis/ValueState.cpp Driver/ASTConsumers.cpp include/clang/Analysis/Analyses/GRSimpleVals.h include/clang/Analysis/PathSensitive/GRExprEngine.h

Ted Kremenek kremenek at apple.com
Mon Feb 18 16:22:37 PST 2008


Author: kremenek
Date: Mon Feb 18 18:22:37 2008
New Revision: 47293

URL: http://llvm.org/viewvc/llvm-project?rev=47293&view=rev
Log:
--grsimple now reports the number of nodes in the ExplodedGraph for
an analyzed function.

GRExprEngine now records stores to "uninitialized lvalues" (which are sinks in
the ExplodedGraph).

Modified:
    cfe/trunk/Analysis/GRExprEngine.cpp
    cfe/trunk/Analysis/GRSimpleVals.cpp
    cfe/trunk/Analysis/ValueState.cpp
    cfe/trunk/Driver/ASTConsumers.cpp
    cfe/trunk/include/clang/Analysis/Analyses/GRSimpleVals.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h

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

==============================================================================
--- cfe/trunk/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/Analysis/GRExprEngine.cpp Mon Feb 18 18:22:37 2008
@@ -304,15 +304,14 @@
 
   RValue R1 = GetValue(PrevState, B->getLHS());
   RValue R2 = GetValue(PrevState, B->getRHS(), hasR2);
-    
-  if (isa<UnknownVal>(R1) && 
-       (isa<UnknownVal>(R2) ||
-        isa<UninitializedVal>(R2))) {    
-
-    Nodify(Dst, B, Pred, SetValue(PrevState, B, R2));
-    return;
-  }    
-  else if (isa<UninitializedVal>(R1)) {
+  
+  if (hasR2) {
+    if (isa<UninitializedVal>(R2) || isa<UnknownVal>(R2)) {
+      Nodify(Dst, B, Pred, SetValue(PrevState, B, R2));
+      return;
+    }
+  }
+  else if (isa<UninitializedVal>(R1) || isa<UnknownVal>(R1)) {
     Nodify(Dst, B, Pred, SetValue(PrevState, B, R1));
     return;
   }
@@ -709,7 +708,12 @@
       switch (Op) {
         case BinaryOperator::Assign: {
           const LValue& L1 = cast<LValue>(V1);
-          Nodify(Dst, B, N2, SetValue(SetValue(St, B, V2), L1, V2));
+
+          if (isa<UninitializedVal>(L1))
+            HandleUninitializedStore(B, N2);
+          else          
+            Nodify(Dst, B, N2, SetValue(SetValue(St, B, V2), L1, V2));
+
           break;
         }
 
@@ -718,6 +722,12 @@
           assert (B->isCompoundAssignmentOp());
                           
           const LValue& L1 = cast<LValue>(V1);
+          
+          if (isa<UninitializedVal>(L1)) {
+            HandleUninitializedStore(B, N2);
+            break;
+          }
+          
           RValue Result = cast<NonLValue>(UnknownVal());
           
           if (Op >= BinaryOperator::AndAssign)
@@ -763,9 +773,14 @@
   }
 }
 
+void GRExprEngine::HandleUninitializedStore(Stmt* S, NodeTy* Pred) {
+  
+  NodeTy* N = Builder->generateNode(S, Pred->getState(), Pred);
+  N->markAsSink();
+  UninitStores.insert(N);
+}
 
-void GRExprEngine::Visit(Stmt* S, GRExprEngine::NodeTy* Pred,
-                        GRExprEngine::NodeSet& Dst) {
+void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) {
 
   // FIXME: add metadata to the CFG so that we can disable
   //  this check when we KNOW that there is no block-level subexpression.
@@ -1137,7 +1152,9 @@
   static std::string getNodeAttributes(const GRExprEngine::NodeTy* N, void*) {
     
     if (GraphPrintCheckerState->isImplicitNullDeref(N) ||
-        GraphPrintCheckerState->isExplicitNullDeref(N))
+        GraphPrintCheckerState->isExplicitNullDeref(N) ||
+        GraphPrintCheckerState->isUninitStore(N) ||
+        GraphPrintCheckerState->isUninitControlFlow(N))
       return "color=\"red\",style=\"filled\"";
     
     return "";
@@ -1172,6 +1189,9 @@
         else if (GraphPrintCheckerState->isExplicitNullDeref(N)) {
           Out << "\\|Explicit-Null Dereference.\\l";
         }
+        else if (GraphPrintCheckerState->isUninitStore(N)) {
+          Out << "\\|Store to Uninitialized LValue.";
+        }
         
         break;
       }

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

==============================================================================
--- cfe/trunk/Analysis/GRSimpleVals.cpp (original)
+++ cfe/trunk/Analysis/GRSimpleVals.cpp Mon Feb 18 18:22:37 2008
@@ -19,11 +19,11 @@
 using namespace clang;
 
 namespace clang {
-  void RunGRSimpleVals(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx,
-                      Diagnostic& Diag, bool Visualize) {
+  unsigned RunGRSimpleVals(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx,
+                           Diagnostic& Diag, bool Visualize) {
     
     if (Diag.hasErrorOccurred())
-      return;
+      return 0;
     
     GRCoreEngine<GRExprEngine> Engine(cfg, FD, Ctx);
     GRExprEngine* CheckerState = &Engine.getCheckerState();
@@ -31,7 +31,7 @@
     CheckerState->setTransferFunctions(GRSV);
     
     // Execute the worklist algorithm.
-    Engine.ExecuteWorkList(10000);
+    Engine.ExecuteWorkList(200);
     
     // Look for explicit-Null dereferences and warn about them.
     for (GRExprEngine::null_iterator I=CheckerState->null_begin(),
@@ -46,7 +46,9 @@
         
 #ifndef NDEBUG
     if (Visualize) CheckerState->ViewGraph();
-#endif  
+#endif
+    
+    return Engine.getGraph().size();
   }
 } // end clang namespace
 

Modified: cfe/trunk/Analysis/ValueState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/ValueState.cpp?rev=47293&r1=47292&r2=47293&view=diff

==============================================================================
--- cfe/trunk/Analysis/ValueState.cpp (original)
+++ cfe/trunk/Analysis/ValueState.cpp Mon Feb 18 18:22:37 2008
@@ -329,7 +329,9 @@
 ValueState
 ValueStateManager::SetValue(ValueState St, const LValue& LV, const RValue& V) {
   
-  assert (!isa<UnknownVal>(LV));
+  if (isa<UnknownVal>(LV))
+    return St;
+  
   assert (!isa<UninitializedVal>(LV));
     
   switch (LV.getSubKind()) {

Modified: cfe/trunk/Driver/ASTConsumers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTConsumers.cpp?rev=47293&r1=47292&r2=47293&view=diff

==============================================================================
--- cfe/trunk/Driver/ASTConsumers.cpp (original)
+++ cfe/trunk/Driver/ASTConsumers.cpp Mon Feb 18 18:22:37 2008
@@ -611,9 +611,9 @@
 
     llvm::Timer T("GRSimpleVals");
     T.startTimer();
-    RunGRSimpleVals(C, FD, *Ctx, Diags, Visualize);
+    unsigned size = RunGRSimpleVals(C, FD, *Ctx, Diags, Visualize);
     T.stopTimer();    
-    llvm::cerr << T.getWallTime() << '\n';
+    llvm::cerr << size << ' ' << T.getWallTime() << '\n';
   }
   else {  
     llvm::cerr << '\n';    

Modified: cfe/trunk/include/clang/Analysis/Analyses/GRSimpleVals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/GRSimpleVals.h?rev=47293&r1=47292&r2=47293&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/Analyses/GRSimpleVals.h (original)
+++ cfe/trunk/include/clang/Analysis/Analyses/GRSimpleVals.h Mon Feb 18 18:22:37 2008
@@ -23,9 +23,9 @@
   /// RunGRSimpleVals - This is a simple driver to run the GRSimpleVals analysis
   ///  on a provided CFG.  This interface will eventually be replaced with
   ///  something more elaborate as the requirements on the interface become
-  ///  clearer.
-  void RunGRSimpleVals(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx,
-                      Diagnostic& Diag, bool Visualize);
+  ///  clearer.  The value returned is the number of nodes in the ExplodedGraph.
+  unsigned RunGRSimpleVals(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx,
+                           Diagnostic& Diag, bool Visualize);
   
 } // end clang namespace
 

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=47293&r1=47292&r2=47293&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Mon Feb 18 18:22:37 2008
@@ -114,13 +114,17 @@
   typedef llvm::SmallPtrSet<NodeTy*,5> UninitBranchesTy;
   UninitBranchesTy UninitBranches;
   
+  /// UninitStores - Sinks in the ExplodedGraph that result from
+  ///  making a store to an uninitialized lvalue.
+  typedef llvm::SmallPtrSet<NodeTy*,5> UninitStoresTy;
+  UninitStoresTy UninitStores;
+  
   /// 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;
   
-  
   bool StateCleaned;
   
 public:
@@ -171,6 +175,10 @@
     return N->isSink() && UninitBranches.count(const_cast<NodeTy*>(N)) != 0;
   }
   
+  bool isUninitStore(const NodeTy* N) const {
+    return N->isSink() && UninitStores.count(const_cast<NodeTy*>(N)) != 0;
+  }
+  
   bool isImplicitNullDeref(const NodeTy* N) const {
     return N->isSink() && ImplicitNullDeref.count(const_cast<NodeTy*>(N)) != 0;
   }
@@ -275,6 +283,10 @@
   ///  The states are not guaranteed to be unique.
   void Nodify(NodeSet& Dst, Stmt* S, NodeTy* Pred, const StateTy::BufferTy& SB);
   
+  /// HandleUninitializedStore - Create the necessary sink node to represent
+  ///  a store to an "uninitialized" LValue.
+  void HandleUninitializedStore(Stmt* S, NodeTy* Pred);
+  
   /// Visit - Transfer function logic for all statements.  Dispatches to
   ///  other functions that handle specific kinds of statements.
   void Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst);





More information about the cfe-commits mailing list