[cfe-commits] r49912 - in /cfe/trunk: include/clang/Analysis/PathSensitive/BugReporter.h include/clang/Analysis/PathSensitive/GRTransferFuncs.h lib/Analysis/CFRefCount.cpp lib/Analysis/GRExprEngine.cpp

Ted Kremenek kremenek at apple.com
Fri Apr 18 12:23:44 PDT 2008


Author: kremenek
Date: Fri Apr 18 14:23:43 2008
New Revision: 49912

URL: http://llvm.org/viewvc/llvm-project?rev=49912&view=rev
Log:
Added "GetErrorNodes()" to BugType so that -trim-egraph can recognize errors
from registered BugTypes.  This helps with debugging.

Add detection of NULL values in ref count checker; this suppresses false positives.

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
    cfe/trunk/lib/Analysis/CFRefCount.cpp
    cfe/trunk/lib/Analysis/GRExprEngine.cpp

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h?rev=49912&r1=49911&r2=49912&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h Fri Apr 18 14:23:43 2008
@@ -19,6 +19,7 @@
 #include "clang/Analysis/PathSensitive/ValueState.h"
 #include "clang/Analysis/PathSensitive/ExplodedGraph.h"
 #include "llvm/ADT/SmallPtrSet.h"
+#include <vector>
 
 namespace clang {
   
@@ -41,6 +42,7 @@
   virtual const char* getDescription() const { return getName(); }
       
   virtual void EmitWarnings(BugReporter& BR) {}
+  virtual void GetErrorNodes(std::vector<ExplodedNode<ValueState>*>& Nodes) {}
 };
   
 class BugReport {

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=49912&r1=49911&r2=49912&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h Fri Apr 18 14:23:43 2008
@@ -99,11 +99,8 @@
 
   // Assumptions.
   
-  virtual ValueState* EvalAssume(ValueState* St, NonLVal Cond, bool Assumption){
-    return St;
-  }
-  
-  virtual ValueState* EvalAssume(ValueState* St, LVal Cond, bool Assumption) {
+  virtual ValueState* EvalAssume(GRExprEngine& Engine, ValueState* St,
+                                 RVal Cond, bool Assumption, bool& isFeasible) {
     return St;
   }
 };

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

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Fri Apr 18 14:23:43 2008
@@ -693,7 +693,12 @@
                           GRStmtNodeBuilder<ValueState>& Builder,
                           ReturnStmt* S,
                           ExplodedNode<ValueState>* Pred);
-  
+
+  // Assumptions.
+
+  virtual ValueState* EvalAssume(GRExprEngine& Engine, ValueState* St,
+                                 RVal Cond, bool Assumption, bool& isFeasible);
+
   // Error iterators.
 
   typedef UseAfterReleasesTy::iterator use_after_iterator;  
@@ -1029,8 +1034,6 @@
 
 // End-of-path.
 
-
-
 ValueState* CFRefCount::HandleSymbolDeath(ValueStateManager& VMgr,
                                           ValueState* St, SymbolID sid,
                                           RefVal V, bool& hasLeak) {
@@ -1066,9 +1069,9 @@
       
   ExplodedNode<ValueState>* N = Builder.MakeNode(St);  
   
-  if (!N)
+  if (!N || Leaked.empty())
     return;
-  
+    
   std::vector<SymbolID>*& LeaksAtNode = Leaks[N];
   assert (!LeaksAtNode);
   LeaksAtNode = new std::vector<SymbolID>();
@@ -1138,6 +1141,44 @@
   Builder.MakeNode(Dst, S, Pred, StateMgr.getPersistentState(StImpl));
 }
 
+// Assumptions.
+
+ValueState* CFRefCount::EvalAssume(GRExprEngine& Eng, ValueState* St,
+                                   RVal Cond, bool Assumption,
+                                   bool& isFeasible) {
+
+  // FIXME: We may add to the interface of EvalAssume the list of symbols
+  //  whose assumptions have changed.  For now we just iterate through the
+  //  bindings and check if any of the tracked symbols are NULL.  This isn't
+  //  too bad since the number of symbols we will track in practice are 
+  //  probably small and EvalAssume is only called at branches and a few
+  //  other places.
+    
+  RefBindings B = GetRefBindings(*St);
+  
+  if (B.isEmpty())
+    return St;
+  
+  bool changed = false;
+
+  for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) {    
+
+    // Check if the symbol is null (or equal to any constant).
+    // If this is the case, stop tracking the symbol.
+  
+    if (St->getSymVal(I.getKey())) {
+      changed = true;
+      B = RefBFactory.Remove(B, I.getKey());
+    }
+  }
+  
+  if (!changed)
+    return St;
+  
+  ValueState StImpl = *St;
+  StImpl.CheckerState = B.getRoot();
+  return Eng.getStateManager().getPersistentState(StImpl);
+}
 
 CFRefCount::RefBindings CFRefCount::Update(RefBindings B, SymbolID sym,
                                            RefVal V, ArgEffect E,
@@ -1280,6 +1321,7 @@
     }
     
     virtual void EmitWarnings(BugReporter& BR);
+    virtual void GetErrorNodes(std::vector<ExplodedNode<ValueState>*>& Nodes);    
   };
   
   //===---------===//
@@ -1465,6 +1507,12 @@
   }  
 }
 
+void Leak::GetErrorNodes(std::vector<ExplodedNode<ValueState>*>& Nodes) {
+  for (CFRefCount::leaks_iterator I=TF.leaks_begin(), E=TF.leaks_end();
+       I!=E; ++I)
+    Nodes.push_back(I->first);
+}
+
 //===----------------------------------------------------------------------===//
 // Transfer function creation for external clients.
 //===----------------------------------------------------------------------===//

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

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Fri Apr 18 14:23:43 2008
@@ -1843,7 +1843,9 @@
                                  bool Assumption, bool& isFeasible) {
                                              
   St = AssumeAux(St, Cond, Assumption, isFeasible);
-  return isFeasible ? St : TF->EvalAssume(St, Cond, Assumption);
+  
+  return isFeasible ? TF->EvalAssume(*this, St, Cond, Assumption, isFeasible)
+                    : St;
 }
 
 ValueState* GRExprEngine::AssumeAux(ValueState* St, LVal Cond,
@@ -1881,7 +1883,9 @@
                                  bool Assumption, bool& isFeasible) {
 
   St = AssumeAux(St, Cond, Assumption, isFeasible);
-  return isFeasible ? St : TF->EvalAssume(St, Cond, Assumption);
+
+  return isFeasible ? TF->EvalAssume(*this, St, Cond, Assumption, isFeasible)
+                    : St;
 }
 
 ValueState* GRExprEngine::AssumeAux(ValueState* St, NonLVal Cond,
@@ -2258,7 +2262,7 @@
 }
 
 template <typename ITERATOR>
-static void AddSources(llvm::SmallVector<GRExprEngine::NodeTy*, 10>& Sources,
+static void AddSources(std::vector<GRExprEngine::NodeTy*>& Sources,
                        ITERATOR I, ITERATOR E) {
   
   llvm::SmallPtrSet<void*,10> CachedSources;
@@ -2280,7 +2284,9 @@
 void GRExprEngine::ViewGraph(bool trim) {
 #ifndef NDEBUG  
   if (trim) {
-    llvm::SmallVector<NodeTy*, 10> Src;
+    std::vector<NodeTy*> Src;
+    
+    // Fixme: Migrate over to the new way of adding nodes.
     AddSources(Src, null_derefs_begin(), null_derefs_end());
     AddSources(Src, undef_derefs_begin(), undef_derefs_end());
     AddSources(Src, explicit_bad_divides_begin(), explicit_bad_divides_end());
@@ -2289,6 +2295,11 @@
     AddSources(Src, undef_arg_begin(), undef_arg_end());
     AddSources(Src, undef_branches_begin(), undef_branches_end());
     
+    // The new way.
+    for (BugTypeSet::iterator I=BugTypes.begin(), E=BugTypes.end(); I!=E; ++I)
+      (*I)->GetErrorNodes(Src);
+      
+    
     ViewGraph(&Src[0], &Src[0]+Src.size());
   }
   else {





More information about the cfe-commits mailing list