[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