]> granicus.if.org Git - clang/commitdiff
[analyzer] Migrate StackAddrLeakChecker to CheckerV2.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 23 Feb 2011 21:04:54 +0000 (21:04 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 23 Feb 2011 21:04:54 +0000 (21:04 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126333 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/StaticAnalyzer/Core/CheckerManager.h
include/clang/StaticAnalyzer/Core/CheckerV2.h
lib/StaticAnalyzer/Checkers/ExprEngine.cpp
lib/StaticAnalyzer/Checkers/StackAddrLeakChecker.cpp
lib/StaticAnalyzer/Core/CheckerManager.cpp

index fd12864e115ec68437a4220f7a3041f831e15b60..9345585b8e1e5e09cdf948bb61ae568cb288b4d2 100644 (file)
@@ -36,6 +36,7 @@ namespace ento {
   class ExplodedNodeSet;
   class ExplodedGraph;
   class GRState;
+  class EndOfFunctionNodeBuilder;
 
 class GraphExpander {
 public:
@@ -186,6 +187,9 @@ public:
   void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
                                  ExprEngine &Eng);
 
+  /// \brief Run checkers for end of path.
+  void runCheckersForEndPath(EndOfFunctionNodeBuilder &B, ExprEngine &Eng);
+
   /// \brief Run checkers for evaluating a call.
   void runCheckersForEvalCall(ExplodedNodeSet &Dst,
                               const ExplodedNodeSet &Src,
@@ -221,6 +225,7 @@ public:
       CheckLocationFunc;
   typedef CheckerFn<ExplodedGraph &, BugReporter &, ExprEngine &>
       CheckEndAnalysisFunc;
+  typedef CheckerFn<EndOfFunctionNodeBuilder &, ExprEngine &> CheckEndPathFunc;
 
   typedef bool (*HandlesStmtFunc)(const Stmt *D);
   void _registerForPreStmt(CheckStmtFunc checkfn,
@@ -235,6 +240,8 @@ public:
 
   void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
 
+  void _registerForEndPath(CheckEndPathFunc checkfn);
+
   class EvalCallFunc {
     typedef bool (*Func)(void *, const CallExpr *, CheckerContext &);
     Func Fn;
@@ -316,6 +323,8 @@ private:
 
   std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
 
+  std::vector<CheckEndPathFunc> EndPathCheckers;
+
   std::vector<EvalCallFunc> EvalCallCheckers;
 };
 
index 5133db4435f491d4df6713cd1810813359708555..a58a593a6c811bcdbf704acd46fd3cca89940c25 100644 (file)
@@ -160,6 +160,21 @@ public:
   }
 };
 
+class EndPath {
+  template <typename CHECKER>
+  static void _checkEndPath(void *checker, EndOfFunctionNodeBuilder &B,
+                            ExprEngine &Eng) {
+    ((const CHECKER *)checker)->checkEndPath(B, Eng);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForEndPath(
+     CheckerManager::CheckEndPathFunc(checker, _checkEndPath<CHECKER>));
+  }
+};
+
 } // end check namespace
 
 namespace eval {
index 3066ec2d3d4e238181b813e58f8773dca600e542..15e6e25b809932f6af79151243065def7b2407a9 100644 (file)
@@ -1443,6 +1443,7 @@ void ExprEngine::processEndOfFunction(EndOfFunctionNodeBuilder& builder) {
     EndOfFunctionNodeBuilder B = builder.withCheckerTag(tag);
     checker->evalEndPath(B, tag, *this);
   }
+  getCheckerManager().runCheckersForEndPath(builder, *this);
 }
 
 /// ProcessSwitch - Called by CoreEngine.  Used to generate successor
index 63da1da43386f03e2aab58462ad6c086b84b38a7..e342fe6dfbf2863d1a8e90497af7bff9e3c431f3 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "ClangSACheckers.h"
+#include "clang/StaticAnalyzer/Core/CheckerV2.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/SmallString.h"
@@ -23,33 +24,22 @@ using namespace clang;
 using namespace ento;
 
 namespace {
-class StackAddrLeakChecker : public CheckerVisitor<StackAddrLeakChecker> {
-  BuiltinBug *BT_stackleak;
-  BuiltinBug *BT_returnstack;
+class StackAddrLeakChecker : public CheckerV2< check::PreStmt<ReturnStmt>,
+                                               check::EndPath > {
+  mutable llvm::OwningPtr<BuiltinBug> BT_stackleak;
+  mutable llvm::OwningPtr<BuiltinBug> BT_returnstack;
 
 public:
-  StackAddrLeakChecker() : BT_stackleak(0), BT_returnstack(0) {}
-  static void *getTag() {
-    static int x;
-    return &x;
-  }
-  void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *RS);
-  void evalEndPath(EndOfFunctionNodeBuilder &B, void *tag, ExprEngine &Eng);
+  void checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const;
+  void checkEndPath(EndOfFunctionNodeBuilder &B, ExprEngine &Eng) const;
 private:
-  void EmitStackError(CheckerContext &C, const MemRegion *R, const Expr *RetE);
-  SourceRange GenName(llvm::raw_ostream &os, const MemRegion *R,
-                      SourceManager &SM);
+  void EmitStackError(CheckerContext &C, const MemRegion *R,
+                      const Expr *RetE) const;
+  static SourceRange GenName(llvm::raw_ostream &os, const MemRegion *R,
+                             SourceManager &SM);
 };
 }
 
-static void RegisterStackAddrLeakChecker(ExprEngine &Eng) {
-  Eng.registerCheck(new StackAddrLeakChecker());
-}
-
-void ento::registerStackAddrLeakChecker(CheckerManager &mgr) {
-  mgr.addCheckerRegisterFunction(RegisterStackAddrLeakChecker);
-}
-
 SourceRange StackAddrLeakChecker::GenName(llvm::raw_ostream &os,
                                           const MemRegion *R,
                                           SourceManager &SM) {
@@ -94,14 +84,15 @@ SourceRange StackAddrLeakChecker::GenName(llvm::raw_ostream &os,
 }
 
 void StackAddrLeakChecker::EmitStackError(CheckerContext &C, const MemRegion *R,
-                                          const Expr *RetE) {
+                                          const Expr *RetE) const {
   ExplodedNode *N = C.generateSink();
 
   if (!N)
     return;
 
   if (!BT_returnstack)
-   BT_returnstack=new BuiltinBug("Return of address to stack-allocated memory");
+   BT_returnstack.reset(
+                 new BuiltinBug("Return of address to stack-allocated memory"));
 
   // Generate a report for this bug.
   llvm::SmallString<512> buf;
@@ -116,8 +107,8 @@ void StackAddrLeakChecker::EmitStackError(CheckerContext &C, const MemRegion *R,
   C.EmitReport(report);
 }
 
-void StackAddrLeakChecker::PreVisitReturnStmt(CheckerContext &C,
-                                              const ReturnStmt *RS) {
+void StackAddrLeakChecker::checkPreStmt(const ReturnStmt *RS,
+                                        CheckerContext &C) const {
   
   const Expr *RetE = RS->getRetValue();
   if (!RetE)
@@ -135,8 +126,8 @@ void StackAddrLeakChecker::PreVisitReturnStmt(CheckerContext &C,
   }
 }
 
-void StackAddrLeakChecker::evalEndPath(EndOfFunctionNodeBuilder &B, void *tag,
-                                       ExprEngine &Eng) {
+void StackAddrLeakChecker::checkEndPath(EndOfFunctionNodeBuilder &B,
+                                        ExprEngine &Eng) const {
 
   const GRState *state = B.getState();
 
@@ -185,11 +176,11 @@ void StackAddrLeakChecker::evalEndPath(EndOfFunctionNodeBuilder &B, void *tag,
     return;
 
   if (!BT_stackleak)
-    BT_stackleak =
+    BT_stackleak.reset(
       new BuiltinBug("Stack address stored into global variable",
                      "Stack address was saved into a global variable. "
                      "This is dangerous because the address will become "
-                     "invalid after returning from the function");
+                     "invalid after returning from the function"));
   
   for (unsigned i = 0, e = cb.V.size(); i != e; ++i) {
     // Generate a report for this bug.
@@ -208,3 +199,7 @@ void StackAddrLeakChecker::evalEndPath(EndOfFunctionNodeBuilder &B, void *tag,
     Eng.getBugReporter().EmitReport(report);
   }
 }
+
+void ento::registerStackAddrLeakChecker(CheckerManager &mgr) {
+  mgr.registerChecker<StackAddrLeakChecker>();
+}
index e24ee52f311bb11b3a21524e5f7c77d7f9ad9583..f909860f7d940587e8d81963112acd1d8e45f5b0 100644 (file)
@@ -217,6 +217,16 @@ void CheckerManager::runCheckersForEndAnalysis(ExplodedGraph &G,
     EndAnalysisCheckers[i](G, BR, Eng);
 }
 
+/// \brief Run checkers for end of path.
+void CheckerManager::runCheckersForEndPath(EndOfFunctionNodeBuilder &B,
+                                           ExprEngine &Eng) {
+  for (unsigned i = 0, e = EndPathCheckers.size(); i != e; ++i) {
+    CheckEndPathFunc fn = EndPathCheckers[i];
+    EndOfFunctionNodeBuilder specialB = B.withCheckerTag(fn.Checker);
+    fn(specialB, Eng);
+  }
+}
+
 /// \brief Run checkers for evaluating a call.
 /// Only one checker will evaluate the call.
 void CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst,
@@ -310,6 +320,10 @@ void CheckerManager::_registerForEndAnalysis(CheckEndAnalysisFunc checkfn) {
   EndAnalysisCheckers.push_back(checkfn);
 }
 
+void CheckerManager::_registerForEndPath(CheckEndPathFunc checkfn) {
+  EndPathCheckers.push_back(checkfn);
+}
+
 void CheckerManager::_registerForEvalCall(EvalCallFunc checkfn) {
   EvalCallCheckers.push_back(checkfn);
 }