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

Ted Kremenek kremenek at apple.com
Thu May 1 16:13:35 PDT 2008


Author: kremenek
Date: Thu May  1 18:13:35 2008
New Revision: 50553

URL: http://llvm.org/viewvc/llvm-project?rev=50553&view=rev
Log:
Added line number diagnostics to indicate the allocation site of the leaked object.

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h
    cfe/trunk/lib/Analysis/BugReporter.cpp
    cfe/trunk/lib/Analysis/CFRefCount.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=50553&r1=50552&r2=50553&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h Thu May  1 18:13:35 2008
@@ -143,6 +143,8 @@
   
   ASTContext& getContext() { return Ctx; }
   
+  SourceManager& getSourceManager() { return Ctx.getSourceManager(); }
+  
   ExplodedGraph<ValueState>& getGraph();
 
   GRExprEngine& getEngine() { return Eng; }

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

==============================================================================
--- cfe/trunk/lib/Analysis/BugReporter.cpp (original)
+++ cfe/trunk/lib/Analysis/BugReporter.cpp Thu May  1 18:13:35 2008
@@ -112,10 +112,8 @@
   if (!S)
     return NULL;
   
-  FullSourceLoc L(S->getLocStart(), BR.getContext().getSourceManager());  
-
-  PathDiagnosticPiece* P =
-    new PathDiagnosticPiece(L, getDescription());
+  FullSourceLoc L(S->getLocStart(), BR.getContext().getSourceManager());
+  PathDiagnosticPiece* P = new PathDiagnosticPiece(L, getDescription());
   
   const SourceRange *Beg, *End;
   getRanges(BR, Beg, End);  

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

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Thu May  1 18:13:35 2008
@@ -14,6 +14,7 @@
 
 #include "GRSimpleVals.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
 #include "clang/Analysis/PathSensitive/ValueState.h"
 #include "clang/Analysis/PathDiagnostic.h"
 #include "clang/Analysis/LocalCheckers.h"
@@ -1446,7 +1447,7 @@
     
     CFRefCount& getTF() { return TF; }
     
-    virtual bool ReportRanges() const { return true; }
+    virtual bool isLeak() const { return false; }
   };
   
   class VISIBILITY_HIDDEN UseAfterRelease : public CFRefBug {
@@ -1494,7 +1495,7 @@
     
     virtual void EmitWarnings(BugReporter& BR);
     virtual void GetErrorNodes(std::vector<ExplodedNode<ValueState>*>& Nodes);
-    virtual bool ReportRanges() const { return false; }
+    virtual bool isLeak() const { return true; }
   };
   
   //===---------===//
@@ -1519,7 +1520,7 @@
     virtual void getRanges(BugReporter& BR, const SourceRange*& beg,           
                            const SourceRange*& end) {
       
-      if (getBugType().ReportRanges())
+      if (getBugType().isLeak())
         RangedBugReport::getRanges(BR, beg, end);
       else {
         beg = 0;
@@ -1527,6 +1528,9 @@
       }
     }
     
+    virtual PathDiagnosticPiece* getEndPath(BugReporter& BR,
+                                            ExplodedNode<ValueState>* N);
+    
     virtual std::pair<const char**,const char**> getExtraDescriptiveText();
     
     virtual PathDiagnosticPiece* VisitNode(ExplodedNode<ValueState>* N,
@@ -1699,6 +1703,52 @@
   return P;
 }
 
+PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& BR,
+                                             ExplodedNode<ValueState>* N) {
+  
+  if (!getBugType().isLeak())
+    return RangedBugReport::getEndPath(BR, N);
+
+  // We are a leak.  Walk up the graph to get to the first node where the
+  // symbol appeared.
+  
+  ExplodedNode<ValueState>* Last = N;
+  typedef CFRefCount::RefBindings RefBindings;
+    
+  // Find the first node that referred to the tracked symbol.
+  
+  while (N) {
+    ValueState* St = N->getState();
+    RefBindings B = RefBindings((RefBindings::TreeTy*) St->CheckerState);
+
+    if (!B.SlimFind(Sym))
+      break;
+        
+    Last = N;
+    N = N->pred_empty() ? NULL : *(N->pred_begin());    
+  }
+  
+  // Get the location.
+  
+  assert (Last);
+  Stmt* FirstStmt = cast<PostStmt>(Last->getLocation()).getStmt();
+
+  unsigned Line =
+   BR.getSourceManager().getLogicalLineNumber(FirstStmt->getLocStart());
+
+  // FIXME: Also get the name of the variable.
+  
+  std::ostringstream os;
+  os << "Object allocated on line " << Line << " is leaked.";
+  
+  Stmt* S = getStmt(BR);
+  assert (S);  
+  FullSourceLoc L(S->getLocStart(), BR.getContext().getSourceManager());    
+  PathDiagnosticPiece* P = new PathDiagnosticPiece(L, os.str());
+    
+  return P;  
+}
+
 void UseAfterRelease::EmitWarnings(BugReporter& BR) {
 
   for (CFRefCount::use_after_iterator I = TF.use_after_begin(),





More information about the cfe-commits mailing list