[cfe-commits] r49180 - in /cfe/trunk: include/clang/Analysis/PathSensitive/BugReporter.h include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h lib/Analysis/BasicObjCFoundationChecks.cpp lib/Analysis/BugReporter.cpp lib/Analysis/GRSimpleVals.cpp lib/Analysis/GRSimpleVals.h

Ted Kremenek kremenek at apple.com
Thu Apr 3 10:57:39 PDT 2008


Author: kremenek
Date: Thu Apr  3 12:57:38 2008
New Revision: 49180

URL: http://llvm.org/viewvc/llvm-project?rev=49180&view=rev
Log:
Hooked up GRSimpleAPICheck and the simple Objective-C Foundation checks to use
the new BugReporter interface.

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h
    cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp
    cfe/trunk/lib/Analysis/BugReporter.cpp
    cfe/trunk/lib/Analysis/GRSimpleVals.cpp
    cfe/trunk/lib/Analysis/GRSimpleVals.h

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=49180&r1=49179&r2=49180&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h Thu Apr  3 12:57:38 2008
@@ -41,6 +41,9 @@
   
   virtual PathDiagnosticPiece* getEndPath(ASTContext& Ctx,
                                           ExplodedNode<ValueState> *N) const;
+  
+  virtual void getRanges(const SourceRange*& beg,
+                         const SourceRange*& end) const;
 };
   
 class BugReporter {

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

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h Thu Apr  3 12:57:38 2008
@@ -22,12 +22,20 @@
   
 class ValueState;
 class Diagnostic;
+class BugReporter;
+class ASTContext;
+class GRExprEngine;
+class PathDiagnosticClient;
+template <typename T> class ExplodedGraph;
+  
   
 class GRSimpleAPICheck : public GRAuditor<ValueState> {
 public:
   GRSimpleAPICheck() {}
   virtual ~GRSimpleAPICheck() {}
-  virtual void ReportResults(Diagnostic& D) {}
+  virtual void ReportResults(Diagnostic& Diag, PathDiagnosticClient* PD,
+                             ASTContext& Ctx, BugReporter& BR,
+                             ExplodedGraph<GRExprEngine>& G) = 0;
 };
 
 } // end namespace clang

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

==============================================================================
--- cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp (original)
+++ cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp Thu Apr  3 12:57:38 2008
@@ -16,9 +16,10 @@
 #include "BasicObjCFoundationChecks.h"
 
 #include "clang/Analysis/PathSensitive/ExplodedGraph.h"
+#include "clang/Analysis/PathSensitive/GRExprEngine.h"
 #include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h"
 #include "clang/Analysis/PathSensitive/ValueState.h"
-#include "clang/Analysis/PathSensitive/AnnotatedPath.h"
+#include "clang/Analysis/PathSensitive/BugReporter.h"
 #include "clang/Analysis/PathDiagnostic.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ASTContext.h"
@@ -28,15 +29,73 @@
 #include <sstream>
 
 using namespace clang;
+
+static ObjCInterfaceType* GetReceiverType(ObjCMessageExpr* ME) {
+  Expr* Receiver = ME->getReceiver();
+  
+  if (!Receiver)
+    return NULL;
+  
+  assert (Receiver->getType()->isPointerType());
+  
+  const PointerType* T = Receiver->getType()->getAsPointerType();
   
+  return dyn_cast<ObjCInterfaceType>(T->getPointeeType().getTypePtr());
+}
+
+static const char* GetReceiverNameType(ObjCMessageExpr* ME) {
+  ObjCInterfaceType* ReceiverType = GetReceiverType(ME);
+  return ReceiverType ? ReceiverType->getDecl()->getIdentifier()->getName()
+                      : NULL;
+}
+
 namespace {
   
+class VISIBILITY_HIDDEN NilArg : public BugDescription {
+  std::string Msg;
+  const char* s;
+  SourceRange R;
+public:
+  NilArg(ObjCMessageExpr* ME, unsigned Arg);
+  virtual ~NilArg() {}
+  
+  virtual const char* getName() const {
+    return "nil argument";
+  }
+  
+  virtual const char* getDescription() const {
+    return s;
+  }
+  
+  virtual void getRanges(const SourceRange*& beg,
+                         const SourceRange*& end) const {
+    beg = &R;
+    end = beg+1;
+  }
+    
+};
+  
+NilArg::NilArg(ObjCMessageExpr* ME, unsigned Arg) : s(NULL) {
+  
+  Expr* E = ME->getArg(Arg);
+  R = E->getSourceRange();
+  
+  std::ostringstream os;
+  
+  os << "Argument to '" << GetReceiverNameType(ME) << "' method '"
+     << ME->getSelector().getName() << "' cannot be nil.";
+  
+  Msg = os.str();
+  s = Msg.c_str();
+}
+  
+  
 class VISIBILITY_HIDDEN BasicObjCFoundationChecks : public GRSimpleAPICheck {
 
   ASTContext &Ctx;
   ValueStateManager* VMgr;
   
-  typedef std::list<AnnotatedPath<ValueState> > ErrorsTy;
+  typedef std::vector<std::pair<NodeTy*,BugDescription*> > ErrorsTy;
   ErrorsTy Errors;
       
   RVal GetRVal(ValueState* St, Expr* E) { return VMgr->GetRVal(St, E); }
@@ -53,12 +112,26 @@
   BasicObjCFoundationChecks(ASTContext& ctx, ValueStateManager* vmgr) 
     : Ctx(ctx), VMgr(vmgr) {}
       
-  virtual ~BasicObjCFoundationChecks() {}
+  virtual ~BasicObjCFoundationChecks() {
+    for (ErrorsTy::iterator I = Errors.begin(), E = Errors.end(); I!=E; ++I)
+      delete I->second;    
+  }
   
   virtual bool Audit(ExplodedNode<ValueState>* N);
   
-  virtual void ReportResults(Diagnostic& D);
-
+  virtual void ReportResults(Diagnostic& Diag, PathDiagnosticClient* PD,
+                             ASTContext& Ctx, BugReporter& BR,
+                             ExplodedGraph<GRExprEngine>& G);
+  
+private:
+  
+  void AddError(NodeTy* N, BugDescription* D) {
+    Errors.push_back(std::make_pair(N, D));
+  }
+  
+  void WarnNilArg(NodeTy* N, ObjCMessageExpr* ME, unsigned Arg) {
+    AddError(N, new NilArg(ME, Arg));
+  }
 };
   
 } // end anonymous namespace
@@ -71,24 +144,7 @@
   return new BasicObjCFoundationChecks(Ctx, VMgr);  
 }
 
-static ObjCInterfaceType* GetReceiverType(ObjCMessageExpr* ME) {
-  Expr* Receiver = ME->getReceiver();
-  
-  if (!Receiver)
-    return NULL;
-  
-  assert (Receiver->getType()->isPointerType());
-  
-  const PointerType* T = Receiver->getType()->getAsPointerType();
-  
-  return dyn_cast<ObjCInterfaceType>(T->getPointeeType().getTypePtr());
-}
 
-static const char* GetReceiverNameType(ObjCMessageExpr* ME) {
-  ObjCInterfaceType* ReceiverType = GetReceiverType(ME);
-  return ReceiverType ? ReceiverType->getDecl()->getIdentifier()->getName()
-                      : NULL;
-}
 
 bool BasicObjCFoundationChecks::Audit(ExplodedNode<ValueState>* N) {
   
@@ -127,43 +183,13 @@
 //===----------------------------------------------------------------------===//
 
 
-void BasicObjCFoundationChecks::Warn(NodeTy* N, Expr* E, const std::string& s) {  
-  Errors.push_back(AnnotatedPath<ValueState>());
-  Errors.back().push_back(N, s, E);
-}
-
-void BasicObjCFoundationChecks::ReportResults(Diagnostic& D) {
-  
-  // FIXME: Expand errors into paths.  For now, just issue warnings.
-  
-  for (ErrorsTy::iterator I=Errors.begin(), E=Errors.end(); I!=E; ++I) {
-      
-    AnnotatedNode<ValueState>& AN = I->back();
-    
-    unsigned diag = D.getCustomDiagID(Diagnostic::Warning,
-                                      AN.getString().c_str());
-    
-    Stmt* S = cast<PostStmt>(AN.getNode()->getLocation()).getStmt();
-    FullSourceLoc L(S->getLocStart(), Ctx.getSourceManager());
-    
-    SourceRange R = AN.getExpr()->getSourceRange();
+void BasicObjCFoundationChecks::ReportResults(Diagnostic& Diag,
+                                              PathDiagnosticClient* PD,
+                                              ASTContext& Ctx, BugReporter& BR,
+                                              ExplodedGraph<GRExprEngine>& G) {
     
-    D.Report(L, diag, &AN.getString(), 1, &R, 1);
-  }
-}
-
-void BasicObjCFoundationChecks::WarnNilArg(NodeTy* N, Expr* E) {
-
-  ObjCMessageExpr* ME =
-    cast<ObjCMessageExpr>(cast<PostStmt>(N->getLocation()).getStmt());    
-  
-  std::ostringstream os;
-  
-  os << "Argument to '" << GetReceiverNameType(ME) << "' method '"
-    << ME->getSelector().getName()
-    << "' cannot be nil.";
-  
-  Warn(N, E, os.str());
+  for (ErrorsTy::iterator I=Errors.begin(), E=Errors.end(); I!=E; ++I)
+    BR.EmitPathWarning(Diag, PD, Ctx, *I->second, G, I->first);
 }
 
 bool BasicObjCFoundationChecks::CheckNilArg(NodeTy* N, unsigned Arg) {
@@ -173,7 +199,7 @@
   Expr * E = ME->getArg(Arg);
   
   if (isNil(GetRVal(N->getState(), E))) {
-    WarnNilArg(N, E);
+    WarnNilArg(N, ME, Arg);
     return true;
   }
   

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

==============================================================================
--- cfe/trunk/lib/Analysis/BugReporter.cpp (original)
+++ cfe/trunk/lib/Analysis/BugReporter.cpp Thu Apr  3 12:57:38 2008
@@ -43,8 +43,7 @@
 
 
 PathDiagnosticPiece*
-BugDescription::getEndPath(ASTContext& Ctx,
-                           ExplodedNode<ValueState> *N) const {
+BugDescription::getEndPath(ASTContext& Ctx, ExplodedNode<ValueState> *N) const {
   
   Stmt* S = GetStmt(N->getLocation());
   
@@ -60,6 +59,12 @@
   return P;
 }
 
+void BugDescription::getRanges(const SourceRange*& beg,
+                               const SourceRange*& end) const {
+  beg = NULL;
+  end = NULL;
+}
+
 void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx,
                                          const BugDescription& B,
                                          ExplodedGraph<GRExprEngine>& G,
@@ -266,7 +271,7 @@
     return;
   
   std::ostringstream os;
-  os << "[CHECKER] " << B.getName();
+  os << "[CHECKER] " << B.getDescription();
   
   unsigned ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning,
                                             os.str().c_str());

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

==============================================================================
--- cfe/trunk/lib/Analysis/GRSimpleVals.cpp (original)
+++ cfe/trunk/lib/Analysis/GRSimpleVals.cpp Thu Apr  3 12:57:38 2008
@@ -164,8 +164,8 @@
 namespace clang {
   
 unsigned RunGRSimpleVals(CFG& cfg, Decl& CD, ASTContext& Ctx,
-                                Diagnostic& Diag, PathDiagnosticClient* PD,
-                                bool Visualize, bool TrimGraph) {
+                         Diagnostic& Diag, PathDiagnosticClient* PD,
+                         bool Visualize, bool TrimGraph) {
   
   GRCoreEngine<GRExprEngine> Eng(cfg, CD, Ctx);
   GRExprEngine* CS = &Eng.getCheckerState();
@@ -217,7 +217,8 @@
   EmitWarning(Diag, PD, Ctx, BR, RetStack(), G,
               CS->ret_stackaddr_begin(), CS->ret_stackaddr_end());
 
-  FoundationCheck.get()->ReportResults(Diag);
+  
+  FoundationCheck.get()->ReportResults(Diag, PD, Ctx, BR, G);
 #ifndef NDEBUG
   if (Visualize) CS->ViewGraph(TrimGraph);
 #endif

Modified: cfe/trunk/lib/Analysis/GRSimpleVals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRSimpleVals.h?rev=49180&r1=49179&r2=49180&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRSimpleVals.h (original)
+++ cfe/trunk/lib/Analysis/GRSimpleVals.h Thu Apr  3 12:57:38 2008
@@ -21,6 +21,9 @@
 
 namespace clang {
   
+class PathDiagnostic;
+class ASTContext;
+  
 class GRSimpleVals : public GRTransferFuncs {
 public:
   GRSimpleVals() {}
@@ -58,6 +61,9 @@
                         CallExpr* CE, LVal L,
                         ExplodedNode<ValueState>* Pred);
   
+  static void GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx,
+                                     ExplodedNode<ValueState>* N);
+  
 protected:
   
   // Equality operators for LVals.





More information about the cfe-commits mailing list