[cfe-commits] r137529 - in /cfe/trunk: include/clang/Analysis/ include/clang/StaticAnalyzer/Core/ include/clang/StaticAnalyzer/Core/PathSensitive/ lib/Analysis/ lib/StaticAnalyzer/Checkers/ lib/StaticAnalyzer/Core/

Ted Kremenek kremenek at apple.com
Fri Aug 12 16:04:46 PDT 2011


Author: kremenek
Date: Fri Aug 12 18:04:46 2011
New Revision: 137529

URL: http://llvm.org/viewvc/llvm-project?rev=137529&view=rev
Log:
[analyzer] change "tag" in ProgramPoint from "void*" to a ProgramPointTag*.

Having a notion of an actual ProgramPointTag will aid in introspection of the analyzer's behavior.
For example, the GraphViz output of the analyzer will pretty-print the tags in a useful manner.

Added:
    cfe/trunk/lib/Analysis/ProgramPoint.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp
Modified:
    cfe/trunk/include/clang/Analysis/ProgramPoint.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
    cfe/trunk/lib/Analysis/CMakeLists.txt
    cfe/trunk/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt
    cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp

Modified: cfe/trunk/include/clang/Analysis/ProgramPoint.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/ProgramPoint.h?rev=137529&r1=137528&r2=137529&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/ProgramPoint.h (original)
+++ cfe/trunk/include/clang/Analysis/ProgramPoint.h Fri Aug 12 18:04:46 2011
@@ -21,15 +21,18 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/ADT/StringRef.h"
 #include <cassert>
 #include <utility>
+#include <string>
 
 namespace clang {
 
-class LocationContext;
 class AnalysisContext;
 class FunctionDecl;
-
+class LocationContext;
+class ProgramPointTag;
+  
 class ProgramPoint {
 public:
   enum Kind { BlockEdgeKind,
@@ -58,15 +61,17 @@
   // The LocationContext could be NULL to allow ProgramPoint to be used in
   // context insensitive analysis.
   const LocationContext *L;
-  const void *Tag;
+  const ProgramPointTag *Tag;
 
+  ProgramPoint();
+  
 protected:
   ProgramPoint(const void* P, Kind k, const LocationContext *l,
-               const void *tag = 0)
+               const ProgramPointTag *tag = 0)
     : Data(P, static_cast<const void*>(NULL)), K(k), L(l), Tag(tag) {}
 
   ProgramPoint(const void* P1, const void* P2, Kind k, const LocationContext *l,
-               const void *tag = 0)
+               const ProgramPointTag *tag = 0)
     : Data(P1, P2), K(k), L(l), Tag(tag) {}
 
 protected:
@@ -76,7 +81,7 @@
 public:
   Kind getKind() const { return K; }
 
-  const void *getTag() const { return Tag; }
+  const ProgramPointTag *getTag() const { return Tag; }
 
   const LocationContext *getLocationContext() const { return L; }
 
@@ -109,7 +114,7 @@
 class BlockEntrance : public ProgramPoint {
 public:
   BlockEntrance(const CFGBlock* B, const LocationContext *L,
-                const void *tag = 0)
+                const ProgramPointTag *tag = 0)
     : ProgramPoint(B, BlockEntranceKind, L, tag) {}
 
   const CFGBlock* getBlock() const {
@@ -123,7 +128,7 @@
   
   /// Create a new BlockEntrance object that is the same as the original
   /// except for using the specified tag value.
-  BlockEntrance withTag(const void *tag) {
+  BlockEntrance withTag(const ProgramPointTag *tag) {
     return BlockEntrance(getBlock(), getLocationContext(), tag);
   }
   
@@ -153,7 +158,7 @@
 class StmtPoint : public ProgramPoint {
 public:
   StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L,
-            const void *tag)
+            const ProgramPointTag *tag)
     : ProgramPoint(S, p2, k, L, tag) {}
 
   const Stmt *getStmt() const { return (const Stmt*) getData1(); }
@@ -170,7 +175,7 @@
 
 class PreStmt : public StmtPoint {
 public:
-  PreStmt(const Stmt *S, const LocationContext *L, const void *tag,
+  PreStmt(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag,
           const Stmt *SubStmt = 0)
     : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {}
 
@@ -184,15 +189,16 @@
 class PostStmt : public StmtPoint {
 protected:
   PostStmt(const Stmt* S, const void* data, Kind k, const LocationContext *L,
-           const void *tag =0)
+           const ProgramPointTag *tag =0)
     : StmtPoint(S, data, k, L, tag) {}
 
 public:
   explicit PostStmt(const Stmt* S, Kind k, 
-                    const LocationContext *L, const void *tag = 0)
+                    const LocationContext *L, const ProgramPointTag *tag = 0)
     : StmtPoint(S, NULL, k, L, tag) {}
 
-  explicit PostStmt(const Stmt* S, const LocationContext *L,const void *tag = 0)
+  explicit PostStmt(const Stmt* S, const LocationContext *L,
+                    const ProgramPointTag *tag = 0)
     : StmtPoint(S, NULL, PostStmtKind, L, tag) {}
 
   static bool classof(const ProgramPoint* Location) {
@@ -225,7 +231,8 @@
 // PostCondition represents the post program point of a branch condition.
 class PostCondition : public PostStmt {
 public:
-  PostCondition(const Stmt* S, const LocationContext *L, const void *tag = 0)
+  PostCondition(const Stmt* S, const LocationContext *L,
+                const ProgramPointTag *tag = 0)
     : PostStmt(S, PostConditionKind, L, tag) {}
 
   static bool classof(const ProgramPoint* Location) {
@@ -236,7 +243,7 @@
 class LocationCheck : public StmtPoint {
 protected:
   LocationCheck(const Stmt *S, const LocationContext *L,
-                ProgramPoint::Kind K, const void *tag)
+                ProgramPoint::Kind K, const ProgramPointTag *tag)
     : StmtPoint(S, NULL, K, L, tag) {}
     
   static bool classof(const ProgramPoint *location) {
@@ -247,7 +254,8 @@
   
 class PreLoad : public LocationCheck {
 public:
-  PreLoad(const Stmt *S, const LocationContext *L, const void *tag = 0)
+  PreLoad(const Stmt *S, const LocationContext *L,
+          const ProgramPointTag *tag = 0)
     : LocationCheck(S, L, PreLoadKind, tag) {}
   
   static bool classof(const ProgramPoint *location) {
@@ -257,7 +265,8 @@
 
 class PreStore : public LocationCheck {
 public:
-  PreStore(const Stmt *S, const LocationContext *L, const void *tag = 0)
+  PreStore(const Stmt *S, const LocationContext *L,
+           const ProgramPointTag *tag = 0)
   : LocationCheck(S, L, PreStoreKind, tag) {}
   
   static bool classof(const ProgramPoint *location) {
@@ -267,7 +276,8 @@
 
 class PostLoad : public PostStmt {
 public:
-  PostLoad(const Stmt* S, const LocationContext *L, const void *tag = 0)
+  PostLoad(const Stmt* S, const LocationContext *L,
+           const ProgramPointTag *tag = 0)
     : PostStmt(S, PostLoadKind, L, tag) {}
 
   static bool classof(const ProgramPoint* Location) {
@@ -277,7 +287,8 @@
 
 class PostStore : public PostStmt {
 public:
-  PostStore(const Stmt* S, const LocationContext *L, const void *tag = 0)
+  PostStore(const Stmt* S, const LocationContext *L,
+            const ProgramPointTag *tag = 0)
     : PostStmt(S, PostStoreKind, L, tag) {}
 
   static bool classof(const ProgramPoint* Location) {
@@ -287,7 +298,8 @@
 
 class PostLValue : public PostStmt {
 public:
-  PostLValue(const Stmt* S, const LocationContext *L, const void *tag = 0)
+  PostLValue(const Stmt* S, const LocationContext *L,
+             const ProgramPointTag *tag = 0)
     : PostStmt(S, PostLValueKind, L, tag) {}
 
   static bool classof(const ProgramPoint* Location) {
@@ -298,7 +310,7 @@
 class PostPurgeDeadSymbols : public PostStmt {
 public:
   PostPurgeDeadSymbols(const Stmt* S, const LocationContext *L,
-                       const void *tag = 0)
+                       const ProgramPointTag *tag = 0)
     : PostStmt(S, PostPurgeDeadSymbolsKind, L, tag) {}
 
   static bool classof(const ProgramPoint* Location) {
@@ -365,6 +377,28 @@
   }
 };
 
+/// ProgramPoints can be "tagged" as representing points specific to a given
+/// analysis entity.  Tags are abstract annotations, with an associated
+/// description and potentially other information.
+class ProgramPointTag {
+public:
+  ProgramPointTag(void *tagKind = 0) : TagKind(tagKind) {}
+  virtual ~ProgramPointTag();
+  virtual StringRef getTagDescription() const = 0;    
+
+protected:
+  const void *getTagKind() { return TagKind; }
+  
+private:
+  const void *TagKind;
+};
+  
+class SimpleProgramPointTag : public ProgramPointTag {
+  std::string desc;
+public:
+  SimpleProgramPointTag(StringRef description);
+  StringRef getTagDescription() const;
+};
 
 } // end namespace clang
 

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h?rev=137529&r1=137528&r2=137529&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h Fri Aug 12 18:04:46 2011
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_SA_CORE_CHECKER
 #define LLVM_CLANG_SA_CORE_CHECKER
 
+#include "clang/Analysis/ProgramPoint.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
 #include "llvm/Support/Casting.h"
@@ -329,6 +330,11 @@
 
 } // end eval namespace
 
+class CheckerBase : public ProgramPointTag {
+public:
+  StringRef getTagDescription() const;
+};
+  
 template <typename CHECK1, typename CHECK2=check::_VoidCheck,
           typename CHECK3=check::_VoidCheck, typename CHECK4=check::_VoidCheck,
           typename CHECK5=check::_VoidCheck, typename CHECK6=check::_VoidCheck,
@@ -341,7 +347,9 @@
 class Checker<check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
                 check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
                 check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
-                check::_VoidCheck, check::_VoidCheck, check::_VoidCheck> {
+                check::_VoidCheck, check::_VoidCheck, check::_VoidCheck> 
+  : public CheckerBase 
+{
 public:
   static void _register(void *checker, CheckerManager &mgr) { }
 };

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h?rev=137529&r1=137528&r2=137529&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h Fri Aug 12 18:04:46 2011
@@ -27,6 +27,7 @@
   class CallExpr;
 
 namespace ento {
+  class CheckerBase;
   class ExprEngine;
   class AnalysisManager;
   class BugReporter;
@@ -55,8 +56,8 @@
   typedef RET (*Func)(void *, P1, P2, P3, P4);
   Func Fn;
 public:
-  void *Checker;
-  CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
+  CheckerBase *Checker;
+  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
   RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { 
     return Fn(Checker, p1, p2, p3, p4);
   } 
@@ -67,8 +68,8 @@
   typedef RET (*Func)(void *, P1, P2, P3);
   Func Fn;
 public:
-  void *Checker;
-  CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
+  CheckerBase *Checker;
+  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
   RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); } 
 };
 
@@ -77,8 +78,8 @@
   typedef RET (*Func)(void *, P1, P2);
   Func Fn;
 public:
-  void *Checker;
-  CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
+  CheckerBase *Checker;
+  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
   RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); } 
 };
 
@@ -87,8 +88,8 @@
   typedef RET (*Func)(void *, P1);
   Func Fn;
 public:
-  void *Checker;
-  CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
+  CheckerBase *Checker;
+  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
   RET operator()(P1 p1) const { return Fn(Checker, p1); } 
 };
 
@@ -97,8 +98,8 @@
   typedef RET (*Func)(void *);
   Func Fn;
 public:
-  void *Checker;
-  CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
+  CheckerBase *Checker;
+  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
   RET operator()() const { return Fn(Checker); } 
 };
 
@@ -115,8 +116,8 @@
 
   const LangOptions &getLangOptions() const { return LangOpts; }
 
-  typedef void *CheckerRef;
-  typedef void *CheckerTag;
+  typedef CheckerBase *CheckerRef;
+  typedef const void *CheckerTag;
   typedef CheckerFn<void ()> CheckerDtor;
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h?rev=137529&r1=137528&r2=137529&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h Fri Aug 12 18:04:46 2011
@@ -28,7 +28,7 @@
   ExprEngine &Eng;
   ExplodedNode *Pred;
   SaveAndRestore<bool> OldSink;
-  const void *checkerTag;
+  const ProgramPointTag *checkerTag;
   SaveAndRestore<ProgramPoint::Kind> OldPointKind;
   SaveOr OldHasGen;
   const GRState *ST;
@@ -39,7 +39,7 @@
 public:
   CheckerContext(ExplodedNodeSet &dst, StmtNodeBuilder &builder,
                  ExprEngine &eng, ExplodedNode *pred,
-                 const void *tag, ProgramPoint::Kind K,
+                 const ProgramPointTag *tag, ProgramPoint::Kind K,
                  bool *respondsToCB = 0,
                  const Stmt *stmt = 0, const GRState *st = 0)
     : Dst(dst), B(builder), Eng(eng), Pred(pred),
@@ -104,7 +104,7 @@
   }
   
   ExplodedNode *generateNode(const Stmt *stmt, const GRState *state,
-                             bool autoTransition = true, const void *tag = 0) {
+                             bool autoTransition = true, const ProgramPointTag *tag = 0) {
     assert(state);
     ExplodedNode *N = generateNodeImpl(stmt, state, false,
                                        tag ? tag : checkerTag);
@@ -123,7 +123,7 @@
   }
 
   ExplodedNode *generateNode(const GRState *state, bool autoTransition = true,
-                             const void *tag = 0) {
+                             const ProgramPointTag *tag = 0) {
     assert(statement && "Only transitions with statements currently supported");
     ExplodedNode *N = generateNodeImpl(statement, state, false,
                                        tag ? tag : checkerTag);
@@ -147,7 +147,7 @@
     Dst.Add(node);
   }
   
-  void addTransition(const GRState *state, const void *tag = 0) {
+  void addTransition(const GRState *state, const ProgramPointTag *tag = 0) {
     assert(state);
     // If the 'state' is not new, we need to check if the cached state 'ST'
     // is new.
@@ -168,7 +168,7 @@
 
 private:
   ExplodedNode *generateNodeImpl(const Stmt* stmt, const GRState *state,
-                             bool markAsSink, const void *tag) {
+                             bool markAsSink, const ProgramPointTag *tag) {
     ExplodedNode *node = B.generateNode(stmt, state, Pred, tag);
     if (markAsSink && node)
       node->markAsSink();

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h?rev=137529&r1=137528&r2=137529&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h Fri Aug 12 18:04:46 2011
@@ -24,6 +24,8 @@
 
 namespace clang {
 
+class ProgramPointTag;
+  
 namespace ento {
 
 //===----------------------------------------------------------------------===//
@@ -170,7 +172,7 @@
   bool BuildSinks;
   bool hasGeneratedNode;
   ProgramPoint::Kind PointKind;
-  const void *Tag;
+  const ProgramPointTag *Tag;
 
   typedef llvm::SmallPtrSet<ExplodedNode*,5> DeferredTy;
   DeferredTy Deferred;
@@ -203,7 +205,7 @@
 
   ExplodedNode* generateNode(const Stmt *S, const GRState *St,
                              ExplodedNode *Pred, ProgramPoint::Kind K,
-                             const void *tag = 0) {
+                             const ProgramPointTag *tag = 0) {
     hasGeneratedNode = true;
 
     if (PurgingDeadSymbols)
@@ -213,7 +215,8 @@
   }
 
   ExplodedNode* generateNode(const Stmt *S, const GRState *St,
-                             ExplodedNode *Pred, const void *tag = 0) {
+                             ExplodedNode *Pred,
+                             const ProgramPointTag *tag = 0) {
     return generateNode(S, St, Pred, PointKind, tag);
   }
 
@@ -230,7 +233,7 @@
   ExplodedNode*
   generateNodeInternal(const Stmt* S, const GRState* State, ExplodedNode* Pred,
                    ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
-                   const void *tag = 0);
+                   const ProgramPointTag *tag = 0);
 
   /// getStmt - Return the current block-level expression associated with
   ///  this builder.
@@ -367,7 +370,7 @@
 
 public:
   SwitchNodeBuilder(ExplodedNode* pred, const CFGBlock* src,
-                      const Expr* condition, CoreEngine* eng)
+                    const Expr* condition, CoreEngine* eng)
   : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
 
   class iterator {
@@ -443,7 +446,7 @@
     : GenericNodeBuilderImpl(eng, pr, p) {}
 
   ExplodedNode *generateNode(const GRState *state, ExplodedNode *pred,
-                             const void *tag, bool asSink) {
+                             const ProgramPointTag *tag, bool asSink) {
     return generateNodeImpl(state, pred, cast<PP_T>(pp).withTag(tag),
                             asSink);
   }
@@ -455,19 +458,19 @@
   CoreEngine &Eng;
   const CFGBlock& B;
   ExplodedNode* Pred;
-  void *Tag;
+  const ProgramPointTag *Tag;
 
 public:
   bool hasGeneratedNode;
 
 public:
   EndOfFunctionNodeBuilder(const CFGBlock* b, ExplodedNode* N, CoreEngine* e,
-                           void *checkerTag = 0)
-    : Eng(*e), B(*b), Pred(N), Tag(checkerTag), hasGeneratedNode(false) {}
+                           const ProgramPointTag *tag = 0)
+    : Eng(*e), B(*b), Pred(N), Tag(tag), hasGeneratedNode(false) {}
 
   ~EndOfFunctionNodeBuilder();
 
-  EndOfFunctionNodeBuilder withCheckerTag(void *tag) {
+  EndOfFunctionNodeBuilder withCheckerTag(const ProgramPointTag *tag) {
     return EndOfFunctionNodeBuilder(&B, Pred, &Eng, tag);
   }
 
@@ -486,7 +489,7 @@
   }
 
   ExplodedNode* generateNode(const GRState* State, ExplodedNode *P = 0,
-                             const void *tag = 0);
+                             const ProgramPointTag *tag = 0);
 
   void GenerateCallExitNode(const GRState *state);
 

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=137529&r1=137528&r2=137529&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Fri Aug 12 18:04:46 2011
@@ -226,7 +226,7 @@
   ExplodedNode* MakeNode(ExplodedNodeSet& Dst, const Stmt* S, 
                          ExplodedNode* Pred, const GRState* St,
                          ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
-                         const void *tag = 0);
+                         const ProgramPointTag *tag = 0);
 
   /// Visit - Transfer function logic for all statements.  Dispatches to
   ///  other functions that handle specific kinds of statements.
@@ -430,24 +430,24 @@
   // same as state->getLValue(Ex).
   /// Simulate a read of the result of Ex.
   void evalLoad(ExplodedNodeSet& Dst, const Expr* Ex, ExplodedNode* Pred,
-                const GRState* St, SVal location, const void *tag = 0,
+                const GRState* St, SVal location, const ProgramPointTag *tag = 0,
                 QualType LoadTy = QualType());
 
   // FIXME: 'tag' should be removed, and a LocationContext should be used
   // instead.
   void evalStore(ExplodedNodeSet& Dst, const Expr* AssignE, const Expr* StoreE,
                  ExplodedNode* Pred, const GRState* St, SVal TargetLV, SVal Val,
-                 const void *tag = 0);
+                 const ProgramPointTag *tag = 0);
 private:
   void evalLoadCommon(ExplodedNodeSet& Dst, const Expr* Ex, ExplodedNode* Pred,
-                      const GRState* St, SVal location, const void *tag,
+                      const GRState* St, SVal location, const ProgramPointTag *tag,
                       QualType LoadTy);
 
   // FIXME: 'tag' should be removed, and a LocationContext should be used
   // instead.
   void evalLocation(ExplodedNodeSet &Dst, const Stmt *S, ExplodedNode* Pred,
                     const GRState* St, SVal location,
-                    const void *tag, bool isLoad);
+                    const ProgramPointTag *tag, bool isLoad);
 
   bool InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, ExplodedNode *Pred);
   

Modified: cfe/trunk/lib/Analysis/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CMakeLists.txt?rev=137529&r1=137528&r2=137529&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CMakeLists.txt (original)
+++ cfe/trunk/lib/Analysis/CMakeLists.txt Fri Aug 12 18:04:46 2011
@@ -9,6 +9,7 @@
   FormatString.cpp
   LiveVariables.cpp
   PrintfFormatString.cpp
+  ProgramPoint.cpp
   PseudoConstantAnalysis.cpp
   ReachableCode.cpp
   ScanfFormatString.cpp

Added: cfe/trunk/lib/Analysis/ProgramPoint.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ProgramPoint.cpp?rev=137529&view=auto
==============================================================================
--- cfe/trunk/lib/Analysis/ProgramPoint.cpp (added)
+++ cfe/trunk/lib/Analysis/ProgramPoint.cpp Fri Aug 12 18:04:46 2011
@@ -0,0 +1,26 @@
+//==- ProgramPoint.cpp - Program Points for Path-Sensitive Analysis -*- 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 interface ProgramPoint, which identifies a
+//  distinct location in a function.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/ProgramPoint.h"
+
+using namespace clang;
+
+ProgramPointTag::~ProgramPointTag() {}
+
+SimpleProgramPointTag::SimpleProgramPointTag(StringRef description)
+  : desc(description) {}
+
+StringRef SimpleProgramPointTag::getTagDescription() const {
+  return desc;
+}

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp?rev=137529&r1=137528&r2=137529&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp Fri Aug 12 18:04:46 2011
@@ -87,12 +87,9 @@
   if (theValueTypePointee != newValueType)
     return false;
 
-  static unsigned magic_load = 0;
-  static unsigned magic_store = 0;
-
-  const void *OSAtomicLoadTag = &magic_load;
-  const void *OSAtomicStoreTag = &magic_store;
-
+  static SimpleProgramPointTag OSAtomicLoadTag("OSAtomicChecker : Load");
+  static SimpleProgramPointTag OSAtomicStoreTag("OSAtomicChecker : Store");
+  
   // Load 'theValue'.
   ExprEngine &Engine = C.getEngine();
   const GRState *state = C.getState();
@@ -111,7 +108,7 @@
     LoadTy = TR->getValueType();
   }
   Engine.evalLoad(Tmp, theValueExpr, C.getPredecessor(), 
-                  state, location, OSAtomicLoadTag, LoadTy);
+                  state, location, &OSAtomicLoadTag, LoadTy);
 
   if (Tmp.empty()) {
     // If no nodes were generated, other checkers must generated sinks. But 
@@ -148,7 +145,8 @@
     SValBuilder &svalBuilder = Engine.getSValBuilder();
 
     // Perform the comparison.
-    DefinedOrUnknownSVal Cmp = svalBuilder.evalEQ(stateLoad,theValueVal,oldValueVal);
+    DefinedOrUnknownSVal Cmp =
+      svalBuilder.evalEQ(stateLoad,theValueVal,oldValueVal);
 
     const GRState *stateEqual = stateLoad->assume(Cmp, true);
 
@@ -165,7 +163,7 @@
       }
 
       Engine.evalStore(TmpStore, NULL, theValueExpr, N, 
-                       stateEqual, location, val, OSAtomicStoreTag);
+                       stateEqual, location, val, &OSAtomicStoreTag);
 
       if (TmpStore.empty()) {
         // If no nodes were generated, other checkers must generated sinks. But 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp?rev=137529&r1=137528&r2=137529&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp Fri Aug 12 18:04:46 2011
@@ -88,11 +88,11 @@
 class GenericNodeBuilderRefCount {
   StmtNodeBuilder *SNB;
   const Stmt *S;
-  const void *tag;
+  const ProgramPointTag *tag;
   EndOfFunctionNodeBuilder *ENB;
 public:
   GenericNodeBuilderRefCount(StmtNodeBuilder &snb, const Stmt *s,
-                     const void *t)
+                     const ProgramPointTag *t)
   : SNB(&snb), S(s), tag(t), ENB(0) {}
 
   GenericNodeBuilderRefCount(EndOfFunctionNodeBuilder &enb)
@@ -1671,9 +1671,11 @@
   BugType *overAutorelease;
   BugType *returnNotOwnedForOwned;
   BugReporter *BR;
+  
+  llvm::DenseMap<SymbolRef, const SimpleProgramPointTag*> DeadSymbolTags;
 
-  const GRState * Update(const GRState * state, SymbolRef sym, RefVal V, ArgEffect E,
-                    RefVal::Kind& hasErr);
+  const GRState * Update(const GRState * state, SymbolRef sym, RefVal V,
+                         ArgEffect E, RefVal::Kind& hasErr);
 
   void ProcessNonLeakError(ExplodedNodeSet& Dst,
                            StmtNodeBuilder& Builder,
@@ -1699,7 +1701,11 @@
       leakWithinFunction(0), leakAtReturn(0), overAutorelease(0),
       returnNotOwnedForOwned(0), BR(0) {}
 
-  virtual ~CFRefCount() {}
+  virtual ~CFRefCount() {
+    for (llvm::DenseMap<SymbolRef, const SimpleProgramPointTag *>::iterator
+         it = DeadSymbolTags.begin(), ei = DeadSymbolTags.end(); it != ei; ++it)
+      delete it->second;
+  }
 
   void RegisterChecks(ExprEngine &Eng);
 
@@ -1757,6 +1763,8 @@
                                const GRState* state,
                                SymbolReaper& SymReaper);
 
+  const ProgramPointTag *getDeadSymbolTag(SymbolRef sym);
+  
   std::pair<ExplodedNode*, const GRState *>
   HandleAutoreleaseCounts(const GRState * state, GenericNodeBuilderRefCount Bd,
                           ExplodedNode* Pred, ExprEngine &Eng,
@@ -2968,7 +2976,7 @@
     return;
 
   // Update the autorelease counts.
-  static unsigned autoreleasetag = 0;
+  static SimpleProgramPointTag autoreleasetag("CFRefCount : Autorelease");
   GenericNodeBuilderRefCount Bd(Builder, S, &autoreleasetag);
   bool stop = false;
   llvm::tie(Pred, state) = HandleAutoreleaseCounts(state , Bd, Pred, Eng, Sym,
@@ -3031,7 +3039,8 @@
 
       if (hasError) {
         // Generate an error node.
-        static int ReturnOwnLeakTag = 0;
+        static SimpleProgramPointTag
+               ReturnOwnLeakTag("CFRefCount : ReturnsOwnLeak");
         state = state->set<RefBindings>(Sym, X);
         ExplodedNode *N =
           Builder.generateNode(PostStmt(S, Pred->getLocationContext(),
@@ -3051,8 +3060,8 @@
     if (RE.isOwned()) {
       // Trying to return a not owned object to a caller expecting an
       // owned object.
-
-      static int ReturnNotOwnedForOwnedTag = 0;
+      static SimpleProgramPointTag
+             ReturnNotOwnedForOwnedTag("CFRefCount : ReturnNotOwnedForOwned");
       state = state->set<RefBindings>(Sym, X ^ RefVal::ErrorReturnedNotOwned);
       if (ExplodedNode *N =
           Builder.generateNode(PostStmt(S, Pred->getLocationContext(),
@@ -3375,6 +3384,17 @@
   ProcessLeaks(state, Leaked, Bd, Eng, Pred);
 }
 
+const ProgramPointTag *CFRefCount::getDeadSymbolTag(SymbolRef sym) {
+  const SimpleProgramPointTag *&tag = DeadSymbolTags[sym];
+  if (!tag) {
+    llvm::SmallString<128> buf;
+    llvm::raw_svector_ostream out(buf);
+    out << "CFRefCount : Dead Symbol : " << sym->getSymbolID();
+    tag = new SimpleProgramPointTag(out.str());
+  }
+  return tag;  
+}
+
 void CFRefCount::evalDeadSymbols(ExplodedNodeSet& Dst,
                                  ExprEngine& Eng,
                                  StmtNodeBuilder& Builder,
@@ -3391,7 +3411,7 @@
     if (const RefVal* T = B.lookup(Sym)){
       // Use the symbol as the tag.
       // FIXME: This might not be as unique as we would like.
-      GenericNodeBuilderRefCount Bd(Builder, S, Sym);
+      GenericNodeBuilderRefCount Bd(Builder, S, getDeadSymbolTag(Sym));
       bool stop = false;
       llvm::tie(Pred, state) = HandleAutoreleaseCounts(state, Bd, Pred, Eng,
                                                        Sym, *T, stop);
@@ -3409,7 +3429,7 @@
         state = HandleSymbolDeath(state, *I, *T, Leaked);
   }
 
-  static unsigned LeakPPTag = 0;
+  static SimpleProgramPointTag LeakPPTag("CFRefCount : Leak");
   {
     GenericNodeBuilderRefCount Bd(Builder, S, &LeakPPTag);
     Pred = ProcessLeaks(state, Leaked, Bd, Eng, Pred);

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt?rev=137529&r1=137528&r2=137529&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt Fri Aug 12 18:04:46 2011
@@ -12,6 +12,7 @@
   BugReporterVisitors.cpp
   CFRefCount.cpp
   CXXExprEngine.cpp
+  Checker.cpp
   CheckerContext.cpp
   CheckerHelpers.cpp
   CheckerManager.cpp

Added: cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp?rev=137529&view=auto
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp (added)
+++ cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp Fri Aug 12 18:04:46 2011
@@ -0,0 +1,22 @@
+//== Checker.cpp - Registration mechanism for checkers -----------*- 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 Checker, used to create and register checkers.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/StaticAnalyzer/Core/Checker.h"
+
+using namespace clang;
+using namespace ento;
+
+StringRef CheckerBase::getTagDescription() const {
+  // FIXME: We want to return the package + name of the checker here.
+  return "A Checker";  
+}

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp?rev=137529&r1=137528&r2=137529&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp Fri Aug 12 18:04:46 2011
@@ -24,7 +24,7 @@
   // add it as a transition.
   if (Dst.size() == size && !B.BuildSinks && !B.hasGeneratedNode) {
     if (ST && ST != Pred->getState()) {
-      static int autoTransitionTag = 0;
+      static SimpleProgramPointTag autoTransitionTag("CheckerContext : auto");
       addTransition(ST, &autoTransitionTag);
     }
     else

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp?rev=137529&r1=137528&r2=137529&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp Fri Aug 12 18:04:46 2011
@@ -13,6 +13,7 @@
 
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/CheckerProvider.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/Analysis/ProgramPoint.h"
 #include "clang/AST/DeclBase.h"

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=137529&r1=137528&r2=137529&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Fri Aug 12 18:04:46 2011
@@ -546,7 +546,8 @@
 }
 
 static ProgramPoint GetProgramPoint(const Stmt *S, ProgramPoint::Kind K,
-                                    const LocationContext *LC, const void *tag){
+                                    const LocationContext *LC,
+                                    const ProgramPointTag *tag){
   switch (K) {
     default:
       assert(false && "Unhandled ProgramPoint kind");    
@@ -571,11 +572,12 @@
 
 ExplodedNode*
 StmtNodeBuilder::generateNodeInternal(const Stmt* S, const GRState* state,
-                                        ExplodedNode* Pred,
-                                        ProgramPoint::Kind K,
-                                        const void *tag) {
+                                      ExplodedNode* Pred,
+                                      ProgramPoint::Kind K,
+                                      const ProgramPointTag *tag) {
   
-  const ProgramPoint &L = GetProgramPoint(S, K, Pred->getLocationContext(),tag);
+  const ProgramPoint &L = GetProgramPoint(S, K, Pred->getLocationContext(),
+                                          tag);
   return generateNodeInternal(L, state, Pred);
 }
 
@@ -732,7 +734,8 @@
 
 ExplodedNode*
 EndOfFunctionNodeBuilder::generateNode(const GRState* State,
-                                       ExplodedNode* P, const void *tag) {
+                                       ExplodedNode* P,
+                                       const ProgramPointTag *tag) {
   hasGeneratedNode = true;
   bool IsNew;
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=137529&r1=137528&r2=137529&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Fri Aug 12 18:04:46 2011
@@ -243,7 +243,7 @@
                                 "Error evaluating statement");
 
   // A tag to track convenience transitions, which can be removed at cleanup.
-  static unsigned tag;
+  static SimpleProgramPointTag cleanupTag("ExprEngine : Clean Node");
   Builder = &builder;
   EntryNode = builder.getPredecessor();
 
@@ -273,7 +273,7 @@
     // up. Since no symbols are dead, we can optimize and not clean out
     // the constraint manager.
     CleanedNode =
-      Builder->generateNode(currentStmt, CleanedState, EntryNode, &tag);
+      Builder->generateNode(currentStmt, CleanedState, EntryNode, &cleanupTag);
     Tmp.Add(CleanedNode);
 
   } else {
@@ -318,7 +318,7 @@
         StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState);
       ExplodedNode *CleanedNode = Builder->generateNode(currentStmt,
                                                         CleanedCheckerSt, *I,
-                                                        &tag);
+                                                        &cleanupTag);
       Tmp.Add(CleanedNode);
     }
   }
@@ -835,8 +835,7 @@
   if (nodeBuilder.getBlockCounter().getNumVisited(
                        pred->getLocationContext()->getCurrentStackFrame(), 
                        block->getBlockID()) >= AMgr.getMaxVisit()) {
-
-    static int tag = 0;
+    static SimpleProgramPointTag tag("ExprEngine : Block count exceeded");
     nodeBuilder.generateNode(pred->getState(), pred, &tag, true);
   }
 }
@@ -846,10 +845,11 @@
 //===----------------------------------------------------------------------===//
 
 ExplodedNode* ExprEngine::MakeNode(ExplodedNodeSet& Dst, const Stmt* S,
-                                     ExplodedNode* Pred, const GRState* St,
-                                     ProgramPoint::Kind K, const void *tag) {
+                                   ExplodedNode* Pred, const GRState* St,
+                                   ProgramPoint::Kind K,
+                                   const ProgramPointTag *tag) {
   assert (Builder && "StmtNodeBuilder not present.");
-  SaveAndRestore<const void*> OldTag(Builder->Tag);
+  SaveAndRestore<const ProgramPointTag*> OldTag(Builder->Tag);
   Builder->Tag = tag;
   return Builder->MakeNode(Dst, S, Pred, St, K);
 }
@@ -1476,7 +1476,7 @@
                              const Expr* LocationE,
                              ExplodedNode* Pred,
                              const GRState* state, SVal location, SVal Val,
-                             const void *tag) {
+                             const ProgramPointTag *tag) {
 
   assert(Builder && "StmtNodeBuilder must be defined.");
 
@@ -1510,7 +1510,7 @@
 void ExprEngine::evalLoad(ExplodedNodeSet& Dst, const Expr *Ex,
                             ExplodedNode* Pred,
                             const GRState* state, SVal location,
-                            const void *tag, QualType LoadTy) {
+                            const ProgramPointTag *tag, QualType LoadTy) {
   assert(!isa<NonLoc>(location) && "location cannot be a NonLoc.");
 
   if (isa<loc::ObjCPropRef>(location)) {
@@ -1527,7 +1527,8 @@
 
     QualType ValTy = TR->getValueType();
     if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) {
-      static int loadReferenceTag = 0;
+      static SimpleProgramPointTag
+             loadReferenceTag("ExprEngine : Load Reference");
       ExplodedNodeSet Tmp;
       evalLoadCommon(Tmp, Ex, Pred, state, location, &loadReferenceTag,
                      getContext().getPointerType(RT->getPointeeType()));
@@ -1548,7 +1549,7 @@
 void ExprEngine::evalLoadCommon(ExplodedNodeSet& Dst, const Expr *Ex,
                                   ExplodedNode* Pred,
                                   const GRState* state, SVal location,
-                                  const void *tag, QualType LoadTy) {
+                                  const ProgramPointTag *tag, QualType LoadTy) {
 
   // Evaluate the location (checks for bad dereferences).
   ExplodedNodeSet Tmp;
@@ -1584,7 +1585,7 @@
 void ExprEngine::evalLocation(ExplodedNodeSet &Dst, const Stmt *S,
                                 ExplodedNode* Pred,
                                 const GRState* state, SVal location,
-                                const void *tag, bool isLoad) {
+                                const ProgramPointTag *tag, bool isLoad) {
   // Early checks for performance reason.
   if (location.isUnknown()) {
     Dst.Add(Pred);
@@ -1603,7 +1604,11 @@
     // "p = 0" is not noted as "Null pointer value stored to 'p'" but
     // instead "int *p" is noted as
     // "Variable 'p' initialized to a null pointer value"
-    ExplodedNode *N = Builder->generateNode(S, state, Pred, this);
+    
+    // FIXME: why is 'tag' not used instead of etag?
+    static SimpleProgramPointTag etag("ExprEngine: Location");
+
+    ExplodedNode *N = Builder->generateNode(S, state, Pred, &etag);
     Src.Add(N ? N : Pred);
   }
   getCheckerManager().runCheckersForLocation(Dst, Src, location, isLoad, S,
@@ -2653,7 +2658,7 @@
     // Record the returned expression in the state. It will be used in
     // processCallExit to bind the return value to the call expr.
     {
-      static int tag = 0;
+      static SimpleProgramPointTag tag("ExprEngine: ReturnStmt");
       const GRState *state = Pred->getState();
       state = state->set<ReturnExpr>(RetE);
       Pred = Builder->generateNode(RetE, state, Pred, &tag);
@@ -3024,7 +3029,13 @@
     Out << "\\|StateID: " << (void*) state
         << " NodeID: " << (void*) N << "\\|";
     state->printDOT(Out, *N->getLocationContext()->getCFG());
-    Out << "\\l";
+
+    Out << "\\l";    
+
+    if (const ProgramPointTag *tag = Loc.getTag()) {
+      Out << "\\|Tag: " << tag->getTagDescription(); 
+      Out << "\\l";
+    }
     return Out.str();
   }
 };





More information about the cfe-commits mailing list