[cfe-commits] r53909 - in /cfe/trunk: Driver/AnalysisConsumer.cpp include/clang/Analysis/LocalCheckers.h include/clang/Analysis/PathSensitive/GRExprEngine.h lib/Analysis/BasicObjCFoundationChecks.cpp lib/Analysis/CFRefCount.cpp lib/Analysis/GRExprEngineInternalChecks.cpp lib/Analysis/GRSimpleVals.cpp lib/Analysis/GRSimpleVals.h

Ted Kremenek kremenek at apple.com
Tue Jul 22 09:21:26 PDT 2008


Author: kremenek
Date: Tue Jul 22 11:21:24 2008
New Revision: 53909

URL: http://llvm.org/viewvc/llvm-project?rev=53909&view=rev
Log:
Moved registration of basic path-sensitive checks from GRSimpleVals.cpp to GRExprEngineInternalChecks.cpp.

Added:
    cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp
Modified:
    cfe/trunk/Driver/AnalysisConsumer.cpp
    cfe/trunk/include/clang/Analysis/LocalCheckers.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
    cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp
    cfe/trunk/lib/Analysis/CFRefCount.cpp
    cfe/trunk/lib/Analysis/GRSimpleVals.cpp
    cfe/trunk/lib/Analysis/GRSimpleVals.h

Modified: cfe/trunk/Driver/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/AnalysisConsumer.cpp?rev=53909&r1=53908&r2=53909&view=diff

==============================================================================
--- cfe/trunk/Driver/AnalysisConsumer.cpp (original)
+++ cfe/trunk/Driver/AnalysisConsumer.cpp Tue Jul 22 11:21:24 2008
@@ -298,7 +298,8 @@
 }
 
 
-static void ActionGRExprEngine(AnalysisManager& mgr, GRTransferFuncs* tf) {
+static void ActionGRExprEngine(AnalysisManager& mgr, GRTransferFuncs* tf,
+                               bool StandardWarnings = true) {
   
   
   llvm::OwningPtr<GRTransferFuncs> TF(tf);
@@ -314,6 +315,11 @@
   GRExprEngine Eng(*mgr.getCFG(), *mgr.getCodeDecl(), mgr.getContext(), *L);
   Eng.setTransferFunctions(tf);
   
+  if (StandardWarnings) {
+    Eng.RegisterInternalChecks();
+    RegisterAppleChecks(Eng);
+  }
+  
   // Execute the worklist algorithm.
   Eng.ExecuteWorkList();
   
@@ -326,14 +332,13 @@
 }
 
 static void ActionCheckerCFRefAux(AnalysisManager& mgr, bool GCEnabled,
-                                    bool StandardWarnings) {
-
+                                  bool StandardWarnings) {
+  
   GRTransferFuncs* TF = MakeCFRefCountTF(mgr.getContext(),
                                          GCEnabled,
-                                         StandardWarnings,
                                          mgr.getLangOptions());
     
-  ActionGRExprEngine(mgr, TF);
+  ActionGRExprEngine(mgr, TF, StandardWarnings);
 }
 
 static void ActionCheckerCFRef(AnalysisManager& mgr) {

Modified: cfe/trunk/include/clang/Analysis/LocalCheckers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/LocalCheckers.h?rev=53909&r1=53908&r2=53909&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/LocalCheckers.h (original)
+++ cfe/trunk/include/clang/Analysis/LocalCheckers.h Tue Jul 22 11:21:24 2008
@@ -30,6 +30,7 @@
 class BugReporter;
 class ObjCImplementationDecl;
 class LangOptions;
+class GRExprEngine;
   
 void CheckDeadStores(LiveVariables& L, BugReporter& BR); 
   
@@ -38,7 +39,6 @@
   
 GRTransferFuncs* MakeGRSimpleValsTF();
 GRTransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
-                                  bool StandardWarnings,
                                   const LangOptions& lopts); 
   
 void CheckObjCDealloc(ObjCImplementationDecl* D, const LangOptions& L,
@@ -46,6 +46,8 @@
   
 void CheckObjCInstMethSignature(ObjCImplementationDecl* ID, BugReporter& BR);
   
+void RegisterAppleChecks(GRExprEngine& Eng);
+  
 } // end namespace clang
 
 #endif

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=53909&r1=53908&r2=53909&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Tue Jul 22 11:21:24 2008
@@ -220,6 +220,8 @@
     BugTypes.push_back(B);
   }
   
+  void RegisterInternalChecks();
+  
   void EmitWarnings(BugReporterData& BRData);  
   
   bool isRetStackAddr(const NodeTy* N) const {

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

==============================================================================
--- cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp (original)
+++ cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp Tue Jul 22 11:21:24 2008
@@ -17,9 +17,12 @@
 
 #include "clang/Analysis/PathSensitive/ExplodedGraph.h"
 #include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h"
+#include "clang/Analysis/PathSensitive/GRExprEngine.h"
 #include "clang/Analysis/PathSensitive/ValueState.h"
 #include "clang/Analysis/PathSensitive/BugReporter.h"
 #include "clang/Analysis/PathDiagnostic.h"
+#include "clang/Analysis/LocalCheckers.h"
+
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ASTContext.h"
@@ -547,3 +550,15 @@
   return new AuditCFNumberCreate(Ctx, VMgr);  
 }
 
+//===----------------------------------------------------------------------===//
+// Check registration.
+
+void clang::RegisterAppleChecks(GRExprEngine& Eng) {
+  ASTContext& Ctx = Eng.getContext();
+  ValueStateManager* VMgr = &Eng.getStateManager();
+
+  Eng.AddCheck(CreateBasicObjCFoundationChecks(Ctx, VMgr),
+               Stmt::ObjCMessageExprClass);
+
+  Eng.AddCheck(CreateAuditCFNumberCreate(Ctx, VMgr), Stmt::CallExprClass);
+}

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

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Tue Jul 22 11:21:24 2008
@@ -1244,7 +1244,6 @@
   // Instance variables.
   
   RetainSummaryManager Summaries;  
-  const bool           EmitStandardWarnings;  
   const LangOptions&   LOpts;
   RefBFactoryTy        RefBFactory;
      
@@ -1293,10 +1292,8 @@
   
 public:
   
-  CFRefCount(ASTContext& Ctx, bool gcenabled, bool StandardWarnings,
-             const LangOptions& lopts)
+  CFRefCount(ASTContext& Ctx, bool gcenabled, const LangOptions& lopts)
     : Summaries(Ctx, gcenabled),
-      EmitStandardWarnings(StandardWarnings),
       LOpts(lopts),
       RetainSelector(GetNullarySelector("retain", Ctx)),
       ReleaseSelector(GetNullarySelector("release", Ctx)),
@@ -2223,7 +2220,6 @@
 } // end anonymous namespace
 
 void CFRefCount::RegisterChecks(GRExprEngine& Eng) {
-  if (EmitStandardWarnings) GRSimpleVals::RegisterChecks(Eng);
   Eng.Register(new UseAfterRelease(*this));
   Eng.Register(new BadRelease(*this));
   Eng.Register(new Leak(*this));
@@ -2593,7 +2589,6 @@
 //===----------------------------------------------------------------------===//
 
 GRTransferFuncs* clang::MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
-                                         bool StandardWarnings,
                                          const LangOptions& lopts) {
-  return new CFRefCount(Ctx, GCEnabled, StandardWarnings, lopts);
+  return new CFRefCount(Ctx, GCEnabled, lopts);
 }  

Added: cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp?rev=53909&view=auto

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp (added)
+++ cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp Tue Jul 22 11:21:24 2008
@@ -0,0 +1,332 @@
+//=-- GRExprEngineInternalChecks.cpp - Builtin GRExprEngine Checks---*- C++ -*-=
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the BugType classes used by GRExprEngine to report
+//  bugs derived from builtin checks in the path-sensitive engine.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/PathSensitive/BugReporter.h"
+#include "clang/Analysis/PathSensitive/GRExprEngine.h"
+#include "llvm/Support/Compiler.h"
+
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Utility functions.
+//===----------------------------------------------------------------------===//
+
+template <typename ITERATOR> inline
+ExplodedNode<ValueState>* GetNode(ITERATOR I) {
+  return *I;
+}
+
+template <> inline
+ExplodedNode<ValueState>* GetNode(GRExprEngine::undef_arg_iterator I) {
+  return I->first;
+}
+
+//===----------------------------------------------------------------------===//
+// Bug Descriptions.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class VISIBILITY_HIDDEN BuiltinBug : public BugTypeCacheLocation {
+  const char* name;
+  const char* desc;
+public:
+  BuiltinBug(const char* n, const char* d) : name(n), desc(d) {}  
+  virtual const char* getName() const { return name; }
+  virtual const char* getDescription() const { return desc; }
+  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) = 0;
+  virtual void EmitWarnings(BugReporter& BR) {
+    EmitBuiltinWarnings(BR, cast<GRBugReporter>(BR).getEngine());
+  }
+  
+  template <typename ITER>
+  void Emit(BugReporter& BR, ITER I, ITER E) {
+    for (; I != E; ++I) {
+      BugReport R(*this, GetNode(I));
+      BR.EmitWarning(R);
+    }
+  }
+};
+  
+class VISIBILITY_HIDDEN NullDeref : public BuiltinBug {
+public:
+  NullDeref() : BuiltinBug("null dereference",
+                           "Dereference of null pointer.") {}
+
+  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
+    Emit(BR, Eng.null_derefs_begin(), Eng.null_derefs_end());
+  }
+};
+  
+class VISIBILITY_HIDDEN UndefinedDeref : public BuiltinBug {
+public:
+  UndefinedDeref() : BuiltinBug("bad dereference",
+                                "Dereference of undefined value.") {}
+  
+  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
+    Emit(BR, Eng.undef_derefs_begin(), Eng.undef_derefs_end());
+  }
+};
+
+class VISIBILITY_HIDDEN DivZero : public BuiltinBug {
+public:
+  DivZero() : BuiltinBug("divide-by-zero",
+                         "Division by zero/undefined value.") {}
+  
+  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
+    Emit(BR, Eng.explicit_bad_divides_begin(), Eng.explicit_bad_divides_end());
+  }
+};
+  
+class VISIBILITY_HIDDEN UndefResult : public BuiltinBug {
+public:
+  UndefResult() : BuiltinBug("undefined result",
+                             "Result of operation is undefined.") {}
+  
+  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
+    Emit(BR, Eng.undef_results_begin(), Eng.undef_results_end());
+  }
+};
+  
+class VISIBILITY_HIDDEN BadCall : public BuiltinBug {
+public:
+  BadCall()
+  : BuiltinBug("invalid function call",
+        "Called function is a NULL or undefined function pointer value.") {}
+  
+  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
+    Emit(BR, Eng.bad_calls_begin(), Eng.bad_calls_end());
+  }
+};
+
+class VISIBILITY_HIDDEN BadArg : public BuiltinBug {
+public:
+  BadArg() : BuiltinBug("bad argument",  
+    "Pass-by-value argument in function is undefined.") {}
+
+  BadArg(const char* d) : BuiltinBug("bad argument", d) {}
+  
+  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
+    for (GRExprEngine::UndefArgsTy::iterator I = Eng.undef_arg_begin(),
+         E = Eng.undef_arg_end(); I!=E; ++I) {
+
+      // Generate a report for this bug.
+      RangedBugReport report(*this, I->first);
+      report.addRange(I->second->getSourceRange());
+
+      // Emit the warning.
+      BR.EmitWarning(report);
+    }
+  }
+};
+  
+class VISIBILITY_HIDDEN BadMsgExprArg : public BadArg {
+public:
+  BadMsgExprArg() 
+    : BadArg("Pass-by-value argument in message expression is undefined.") {}
+  
+  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
+    for (GRExprEngine::UndefArgsTy::iterator I=Eng.msg_expr_undef_arg_begin(),
+         E = Eng.msg_expr_undef_arg_end(); I!=E; ++I) {
+      
+      // Generate a report for this bug.
+      RangedBugReport report(*this, I->first);
+      report.addRange(I->second->getSourceRange());
+      
+      // Emit the warning.
+      BR.EmitWarning(report);
+    }    
+  }
+};
+  
+class VISIBILITY_HIDDEN BadReceiver : public BuiltinBug {
+public:  
+  BadReceiver()
+  : BuiltinBug("bad receiver",
+               "Receiver in message expression is an uninitialized value.") {}
+  
+  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
+    for (GRExprEngine::UndefReceiversTy::iterator I=Eng.undef_receivers_begin(),
+         End = Eng.undef_receivers_end(); I!=End; ++I) {
+      
+      // Generate a report for this bug.
+      RangedBugReport report(*this, *I);
+      
+      ExplodedNode<ValueState>* N = *I;
+      Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
+      Expr* E = cast<ObjCMessageExpr>(S)->getReceiver();
+      assert (E && "Receiver cannot be NULL");
+      report.addRange(E->getSourceRange());
+      
+      // Emit the warning.
+      BR.EmitWarning(report);
+    }    
+  }
+};
+  
+class VISIBILITY_HIDDEN RetStack : public BuiltinBug {
+public:
+  RetStack() : BuiltinBug("return of stack address",
+                          "Address of stack-allocated variable returned.") {}
+  
+  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
+    Emit(BR, Eng.ret_stackaddr_begin(), Eng.ret_stackaddr_end());
+  }
+};
+
+
+class VISIBILITY_HIDDEN UndefBranch : public BuiltinBug {
+  struct VISIBILITY_HIDDEN FindUndefExpr {
+    ValueStateManager& VM;
+    const ValueState* St;
+    
+    FindUndefExpr(ValueStateManager& V, const ValueState* S) : VM(V), St(S) {}
+    
+    Expr* FindExpr(Expr* Ex) {
+      
+      if (!MatchesCriteria(Ex))
+        return 0;    
+      
+      for (Stmt::child_iterator I=Ex->child_begin(), E=Ex->child_end(); I!=E; ++I)
+        if (Expr* ExI = dyn_cast_or_null<Expr>(*I)) {
+          Expr* E2 = FindExpr(ExI);
+          if (E2) return E2;
+        }
+      
+      return Ex;
+    }
+    
+    bool MatchesCriteria(Expr* Ex) { return VM.GetRVal(St, Ex).isUndef(); }
+  };
+  
+public:
+  UndefBranch()
+    : BuiltinBug("uninitialized value",
+                 "Branch condition evaluates to an uninitialized value.") {}
+  
+  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
+    for (GRExprEngine::undef_branch_iterator I=Eng.undef_branches_begin(),
+         E=Eng.undef_branches_end(); I!=E; ++I) {
+
+      // What's going on here: we want to highlight the subexpression of the
+      // condition that is the most likely source of the "uninitialized
+      // branch condition."  We do a recursive walk of the condition's
+      // subexpressions and roughly look for the most nested subexpression
+      // that binds to Undefined.  We then highlight that expression's range.
+
+      BlockEdge B = cast<BlockEdge>((*I)->getLocation());
+      Expr* Ex = cast<Expr>(B.getSrc()->getTerminatorCondition());
+      assert (Ex && "Block must have a terminator.");
+
+      // Get the predecessor node and check if is a PostStmt with the Stmt
+      // being the terminator condition.  We want to inspect the state
+      // of that node instead because it will contain main information about
+      // the subexpressions.
+
+      assert (!(*I)->pred_empty());
+
+      // Note: any predecessor will do.  They should have identical state,
+      // since all the BlockEdge did was act as an error sink since the value
+      // had to already be undefined.
+      ExplodedNode<ValueState> *N = *(*I)->pred_begin();
+      ProgramPoint P = N->getLocation();
+
+      const ValueState* St = (*I)->getState();
+
+      if (PostStmt* PS = dyn_cast<PostStmt>(&P))
+        if (PS->getStmt() == Ex)
+          St = N->getState();
+
+      FindUndefExpr FindIt(Eng.getStateManager(), St);
+      Ex = FindIt.FindExpr(Ex);
+
+      RangedBugReport R(*this, *I);
+      R.addRange(Ex->getSourceRange());
+
+      BR.EmitWarning(R);
+    }
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// __attribute__(nonnull) checking
+
+class VISIBILITY_HIDDEN CheckAttrNonNull : public GRSimpleAPICheck {
+  SimpleBugType BT;
+  std::list<RangedBugReport> Reports;
+  
+public:
+  CheckAttrNonNull() :
+  BT("'nonnull' argument passed null",
+     "Null pointer passed as an argument to a 'nonnull' parameter") {}
+
+  virtual bool Audit(ExplodedNode<ValueState>* N, ValueStateManager& VMgr) {
+    CallExpr* CE = cast<CallExpr>(cast<PostStmt>(N->getLocation()).getStmt());
+    const ValueState* state = N->getState();
+    
+    RVal X = VMgr.GetRVal(state, CE->getCallee());
+    
+    if (!isa<lval::FuncVal>(X))
+      return false;
+    
+    FunctionDecl* FD = dyn_cast<FunctionDecl>(cast<lval::FuncVal>(X).getDecl());
+    const NonNullAttr* Att = FD->getAttr<NonNullAttr>();
+    
+    if (!Att)
+      return false;
+    
+    // Iterate through the arguments of CE and check them for null.
+    
+    unsigned idx = 0;
+    bool hasError = false;
+    
+    for (CallExpr::arg_iterator I=CE->arg_begin(), E=CE->arg_end(); I!=E;
+         ++I, ++idx) {
+      
+      if (!VMgr.isEqual(state, *I, 0) || !Att->isNonNull(idx))
+        continue;
+      
+      RangedBugReport R(BT, N);
+      R.addRange((*I)->getSourceRange());
+      Reports.push_back(R);
+      hasError = true;
+    }
+    
+    return hasError;
+  }
+  
+  virtual void EmitWarnings(BugReporter& BR) {
+    for (std::list<RangedBugReport>::iterator I=Reports.begin(),
+         E=Reports.end(); I!=E; ++I)
+      BR.EmitWarning(*I);
+  }
+};
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Check registration.
+
+void GRExprEngine::RegisterInternalChecks() {
+  Register(new NullDeref());
+  Register(new UndefinedDeref());
+  Register(new UndefBranch());
+  Register(new DivZero());
+  Register(new UndefResult());
+  Register(new BadCall());
+  Register(new RetStack());
+  Register(new BadArg());
+  Register(new BadMsgExprArg());
+  Register(new BadReceiver());
+  AddCheck(new CheckAttrNonNull(), Stmt::CallExprClass); 
+}

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

==============================================================================
--- cfe/trunk/lib/Analysis/GRSimpleVals.cpp (original)
+++ cfe/trunk/lib/Analysis/GRSimpleVals.cpp Tue Jul 22 11:21:24 2008
@@ -27,400 +27,6 @@
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
-// Utility functions.
-//===----------------------------------------------------------------------===//
-
-template <typename ITERATOR> inline
-ExplodedNode<ValueState>* GetNode(ITERATOR I) {
-  return *I;
-}
-
-template <> inline
-ExplodedNode<ValueState>* GetNode(GRExprEngine::undef_arg_iterator I) {
-  return I->first;
-}
-
-template <typename ITER>
-void GenericEmitWarnings(BugReporter& BR, BugType& D, ITER I, ITER E) {
-  
-  for (; I != E; ++I) {
-    BugReport R(D, GetNode(I));    
-    BR.EmitWarning(R);
-  }
-}
-
-//===----------------------------------------------------------------------===//
-// Bug Descriptions.
-//===----------------------------------------------------------------------===//
-
-namespace {
-  
-class VISIBILITY_HIDDEN NullDeref : public BugTypeCacheLocation {
-public:
-  virtual const char* getName() const {
-    return "null dereference";
-  }
-  
-  virtual const char* getDescription() const {
-    return "Dereference of null pointer.";
-  }
-  
-  virtual void EmitWarnings(BugReporter& BR) {
-    GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
-    GenericEmitWarnings(BR, *this, Eng.null_derefs_begin(),
-                        Eng.null_derefs_end());
-  }
-};
-
-class VISIBILITY_HIDDEN UndefDeref : public BugTypeCacheLocation {
-public:
-  virtual const char* getName() const {
-    return "bad dereference";
-  }
-  
-  virtual const char* getDescription() const {
-    return "Dereference of undefined value.";
-  }
-  
-  virtual void EmitWarnings(BugReporter& BR) {
-    GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
-    GenericEmitWarnings(BR, *this, Eng.undef_derefs_begin(),
-                        Eng.undef_derefs_end());
-  }
-};
-  
-class VISIBILITY_HIDDEN UndefBranch : public BugTypeCacheLocation {
-public:
-  virtual const char* getName() const {
-    return "uninitialized value";
-  }
-  
-  virtual const char* getDescription() const {
-    return "Branch condition evaluates to an uninitialized value.";
-  }
-  
-  virtual void EmitWarnings(BugReporter& BR);
-};
-  
-class VISIBILITY_HIDDEN DivZero : public BugTypeCacheLocation {
-public:
-  virtual const char* getName() const {
-    return "divide-by-zero";
-  }
-  
-  virtual const char* getDescription() const {
-    return "Division by zero/undefined value.";
-  }
-  
-  virtual void EmitWarnings(BugReporter& BR) {
-    GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
-    GenericEmitWarnings(BR, *this, Eng.explicit_bad_divides_begin(),
-                        Eng.explicit_bad_divides_end());
-  }
-};
-
-class VISIBILITY_HIDDEN UndefResult : public BugTypeCacheLocation {
-public:
-  virtual const char* getName() const {
-    return "undefined result";
-  }
-  
-  virtual const char* getDescription() const {
-    return "Result of operation is undefined.";
-  }
-  
-  virtual void EmitWarnings(BugReporter& BR) {
-    GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
-    GenericEmitWarnings(BR, *this, Eng.undef_results_begin(),
-                        Eng.undef_results_end());
-  }
-};
-  
-class VISIBILITY_HIDDEN BadCall : public BugTypeCacheLocation {
-public:
-  virtual const char* getName() const {
-    return "invalid function call";
-  }
-  
-  virtual const char* getDescription() const {
-    return "Called function is a NULL or undefined function pointer value.";
-  }
-  
-  virtual void EmitWarnings(BugReporter& BR) {
-    GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
-    GenericEmitWarnings(BR, *this, Eng.bad_calls_begin(),
-                        Eng.bad_calls_end());
-  }
-};
-  
-  
-class VISIBILITY_HIDDEN BadArg : public BugTypeCacheLocation {
-public:
-  
-  virtual ~BadArg() {}
-  
-  virtual const char* getName() const {
-    return "bad argument";
-  }
-  
-  virtual const char* getDescription() const {
-    return "Pass-by-value argument in function is undefined.";
-  }  
-
-  virtual void EmitWarnings(BugReporter& BR) {
-    GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
-
-    for (GRExprEngine::UndefArgsTy::iterator I = Eng.undef_arg_begin(),
-         E = Eng.undef_arg_end(); I!=E; ++I) {
-      
-      // Generate a report for this bug.
-      RangedBugReport report(*this, I->first);
-      report.addRange(I->second->getSourceRange());
-
-      // Emit the warning.
-      BR.EmitWarning(report);
-    }
-
-  }
-};
-  
-class VISIBILITY_HIDDEN BadMsgExprArg : public BadArg {
-public:
-  virtual const char* getName() const {
-    return "bad argument";
-  }
-  
-  virtual const char* getDescription() const {
-    return "Pass-by-value argument in message expression is undefined.";
-  }
-  
-  virtual void EmitWarnings(BugReporter& BR) {
-    GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
-    
-    for (GRExprEngine::UndefArgsTy::iterator I=Eng.msg_expr_undef_arg_begin(),
-         E = Eng.msg_expr_undef_arg_end(); I!=E; ++I) {
-      
-      // Generate a report for this bug.
-      RangedBugReport report(*this, I->first);
-      report.addRange(I->second->getSourceRange());
-      
-      // Emit the warning.
-      BR.EmitWarning(report);
-    }    
-  }
-};
-
-class VISIBILITY_HIDDEN BadReceiver : public BugTypeCacheLocation {
-public:  
-  virtual const char* getName() const {
-    return "bad receiver";
-  }
-  
-  virtual const char* getDescription() const {
-    return "Receiver in message expression is an uninitialized value.";
-  }
-  
-  virtual void EmitWarnings(BugReporter& BR) {
-    GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
-    
-    for (GRExprEngine::UndefReceiversTy::iterator I=Eng.undef_receivers_begin(),
-         End = Eng.undef_receivers_end(); I!=End; ++I) {
-          
-      // Generate a report for this bug.
-      RangedBugReport report(*this, *I);
-      
-      ExplodedNode<ValueState>* N = *I;
-      Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
-      Expr* E = cast<ObjCMessageExpr>(S)->getReceiver();
-      assert (E && "Receiver cannot be NULL");
-      report.addRange(E->getSourceRange());
-      
-      // Emit the warning.
-      BR.EmitWarning(report);
-    }    
-  }
-};
-  
-class VISIBILITY_HIDDEN RetStack : public BugTypeCacheLocation {
-public:
-  virtual const char* getName() const {
-    return "return of stack address";
-  }
-  
-  virtual const char* getDescription() const {
-    return "Address of stack-allocated variable returned.";
-  }
-  
-  virtual void EmitWarnings(BugReporter& BR) {
-    GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
-    GenericEmitWarnings(BR, *this, Eng.ret_stackaddr_begin(),
-                        Eng.ret_stackaddr_end());
-  }
-};
-  
-} // end anonymous namespace
-
-
-namespace {
-
-struct VISIBILITY_HIDDEN FindUndefExpr {
-  ValueStateManager& VM;
-  const ValueState* St;
-  
-  FindUndefExpr(ValueStateManager& V, const ValueState* S) : VM(V), St(S) {}
-  
-  Expr* FindExpr(Expr* Ex) {
-    
-    if (!MatchesCriteria(Ex))
-      return 0;    
-        
-    for (Stmt::child_iterator I=Ex->child_begin(), E=Ex->child_end(); I!=E; ++I)
-      if (Expr* ExI = dyn_cast_or_null<Expr>(*I)) {
-        Expr* E2 = FindExpr(ExI);
-        if (E2) return E2;
-      }
-    
-    return Ex;
-  }
-  
-  bool MatchesCriteria(Expr* Ex) { return VM.GetRVal(St, Ex).isUndef(); }  
-};
-  
-} // end anonymous namespace
-  
-  
-void UndefBranch::EmitWarnings(BugReporter& BR) {
-
-  GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
-  
-  for (GRExprEngine::undef_branch_iterator I=Eng.undef_branches_begin(),
-       E=Eng.undef_branches_end(); I!=E; ++I) {
-
-    // What's going on here: we want to highlight the subexpression of the
-    // condition that is the most likely source of the "uninitialized
-    // branch condition."  We do a recursive walk of the condition's
-    // subexpressions and roughly look for the most nested subexpression
-    // that binds to Undefined.  We then highlight that expression's range.
-    
-    BlockEdge B = cast<BlockEdge>((*I)->getLocation());
-    Expr* Ex = cast<Expr>(B.getSrc()->getTerminatorCondition());
-    assert (Ex && "Block must have a terminator.");
-    
-    // Get the predecessor node and check if is a PostStmt with the Stmt
-    // being the terminator condition.  We want to inspect the state
-    // of that node instead because it will contain main information about
-    // the subexpressions.
-    
-    assert (!(*I)->pred_empty());
-    
-    // Note: any predecessor will do.  They should have identical state,
-    // since all the BlockEdge did was act as an error sink since the value
-    // had to already be undefined.
-    ExplodedNode<ValueState> *N = *(*I)->pred_begin();
-    ProgramPoint P = N->getLocation();
-
-    const ValueState* St = (*I)->getState();
-    
-    if (PostStmt* PS = dyn_cast<PostStmt>(&P))
-      if (PS->getStmt() == Ex)
-        St = N->getState();
-        
-    FindUndefExpr FindIt(Eng.getStateManager(), St);
-    Ex = FindIt.FindExpr(Ex);
-    
-    RangedBugReport R(*this, *I);
-    R.addRange(Ex->getSourceRange());
-    
-    BR.EmitWarning(R);
-  }
-}
-
-//===----------------------------------------------------------------------===//
-// __attribute__(nonnull) checking
-
-class VISIBILITY_HIDDEN CheckAttrNonNull : public GRSimpleAPICheck {
-  SimpleBugType BT;
-  std::list<RangedBugReport> Reports;
-
-public:
-  CheckAttrNonNull() :
-    BT("'nonnull' argument passed null",
-       "Null pointer passed as an argument to a 'nonnull' parameter") {}
-  
-
-  virtual bool Audit(ExplodedNode<ValueState>* N, ValueStateManager& VMgr) {
-    CallExpr* CE = cast<CallExpr>(cast<PostStmt>(N->getLocation()).getStmt());
-    const ValueState* state = N->getState();
-    
-    RVal X = VMgr.GetRVal(state, CE->getCallee());
-
-    if (!isa<lval::FuncVal>(X))
-      return false;
-    
-    FunctionDecl* FD = dyn_cast<FunctionDecl>(cast<lval::FuncVal>(X).getDecl());
-    const NonNullAttr* Att = FD->getAttr<NonNullAttr>();
-    
-    if (!Att)
-      return false;
-    
-    // Iterate through the arguments of CE and check them for null.
-    
-    unsigned idx = 0;
-    bool hasError = false;
-    
-    for (CallExpr::arg_iterator I=CE->arg_begin(), E=CE->arg_end(); I!=E;
-         ++I, ++idx) {
-    
-      if (!VMgr.isEqual(state, *I, 0) || !Att->isNonNull(idx))
-        continue;
-      
-      RangedBugReport R(BT, N);
-      R.addRange((*I)->getSourceRange());
-      Reports.push_back(R);
-      hasError = true;
-    }
-    
-    return hasError;
-  }
-  
-  virtual void EmitWarnings(BugReporter& BR) {
-    for (std::list<RangedBugReport>::iterator I=Reports.begin(),
-         E=Reports.end(); I!=E; ++I)
-      BR.EmitWarning(*I);
-  }
-};
-
-//===----------------------------------------------------------------------===//
-// Check registration.
-
-void GRSimpleVals::RegisterChecks(GRExprEngine& Eng) {
-  
-  // Path-sensitive checks.
-  Eng.Register(new NullDeref());
-  Eng.Register(new UndefDeref());
-  Eng.Register(new UndefBranch());
-  Eng.Register(new DivZero());
-  Eng.Register(new UndefResult());
-  Eng.Register(new BadCall());
-  Eng.Register(new RetStack());
-  Eng.Register(new BadArg());
-  Eng.Register(new BadMsgExprArg());
-  Eng.Register(new BadReceiver());
-  
-  // Add extra checkers.
-  ASTContext& Ctx = Eng.getContext();
-  ValueStateManager* VMgr = &Eng.getStateManager();
-
-  GRSimpleAPICheck* Check = CreateBasicObjCFoundationChecks(Ctx, VMgr);
-  Eng.AddCheck(Check, Stmt::ObjCMessageExprClass);
-  
-  Check = CreateAuditCFNumberCreate(Ctx, VMgr);
-  Eng.AddCheck(Check, Stmt::CallExprClass);
-  
-  Eng.AddCheck(new CheckAttrNonNull(), Stmt::CallExprClass);  
-}
-
-//===----------------------------------------------------------------------===//
 // Transfer Function creation for External clients.
 //===----------------------------------------------------------------------===//
 

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

==============================================================================
--- cfe/trunk/lib/Analysis/GRSimpleVals.h (original)
+++ cfe/trunk/lib/Analysis/GRSimpleVals.h Tue Jul 22 11:21:24 2008
@@ -35,8 +35,6 @@
   GRSimpleVals() {}
   virtual ~GRSimpleVals() {}
   
-  virtual void RegisterChecks(GRExprEngine& Eng);
-  
   // Casts.
   
   virtual RVal EvalCast(GRExprEngine& Engine, NonLVal V, QualType CastT);





More information about the cfe-commits mailing list