summaryrefslogtreecommitdiffstats
path: root/include/clang/StaticAnalyzer
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/StaticAnalyzer')
-rw-r--r--include/clang/StaticAnalyzer/Checkers/CheckerBase.td11
-rw-r--r--include/clang/StaticAnalyzer/Checkers/LocalCheckers.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h14
-rw-r--r--include/clang/StaticAnalyzer/Core/Checker.h (renamed from include/clang/StaticAnalyzer/Core/CheckerV2.h)126
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerManager.h206
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerProvider.h1
-rw-r--r--include/clang/StaticAnalyzer/Core/PathDiagnosticClients.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h12
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Checker.h166
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.def48
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.h103
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h38
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h5
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h109
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h16
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h26
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h155
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Store.h27
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h50
20 files changed, 479 insertions, 642 deletions
diff --git a/include/clang/StaticAnalyzer/Checkers/CheckerBase.td b/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
index e452ccf..11f1e5d 100644
--- a/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
+++ b/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
@@ -11,18 +11,19 @@
//
//===----------------------------------------------------------------------===//
+class CheckerGroup<string name> {
+ string GroupName = name;
+}
+class InGroup<CheckerGroup G> { CheckerGroup Group = G; }
+
class Package<string name> {
string PackageName = name;
bit Hidden = 0;
Package ParentPackage;
+ CheckerGroup Group;
}
class InPackage<Package P> { Package ParentPackage = P; }
-class CheckerGroup<string name> {
- string GroupName = name;
-}
-class InGroup<CheckerGroup G> { CheckerGroup Group = G; }
-
// All checkers are an indirect subclass of this.
class Checker<string name = ""> {
string CheckerName = name;
diff --git a/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h b/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h
index afba12d..2a3d43e 100644
--- a/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h
+++ b/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h
@@ -39,8 +39,6 @@ class ExprEngine;
TransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
const LangOptions& lopts);
-void RegisterExperimentalChecks(ExprEngine &Eng);
-
void RegisterCallInliner(ExprEngine &Eng);
} // end GR namespace
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
index 93d7958..3acbcd6 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -126,7 +126,7 @@ public:
/// getLocation - Return the "definitive" location of the reported bug.
/// While a bug can span an entire path, usually there is a specific
- /// location that can be used to identify where the key issue occured.
+ /// location that can be used to identify where the key issue occurred.
/// This location is used by clients rendering diagnostics.
virtual SourceLocation getLocation() const;
@@ -219,6 +219,18 @@ public:
virtual std::pair<ranges_iterator, ranges_iterator> getRanges() const {
return std::make_pair(Ranges.begin(), Ranges.end());
}
+
+ virtual void Profile(llvm::FoldingSetNodeID& hash) const {
+ BugReport::Profile(hash);
+ for (llvm::SmallVectorImpl<SourceRange>::const_iterator I =
+ Ranges.begin(), E = Ranges.end(); I != E; ++I) {
+ const SourceRange range = *I;
+ if (!range.isValid())
+ continue;
+ hash.AddInteger(range.getBegin().getRawEncoding());
+ hash.AddInteger(range.getEnd().getRawEncoding());
+ }
+ }
};
class EnhancedBugReport : public RangedBugReport {
diff --git a/include/clang/StaticAnalyzer/Core/CheckerV2.h b/include/clang/StaticAnalyzer/Core/Checker.h
index e080d19..8c2ffc6 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerV2.h
+++ b/include/clang/StaticAnalyzer/Core/Checker.h
@@ -1,4 +1,4 @@
-//== CheckerV2.h - Registration mechanism for checkers -----------*- C++ -*--=//
+//== Checker.h - Registration mechanism for checkers -------------*- C++ -*--=//
//
// The LLVM Compiler Infrastructure
//
@@ -7,14 +7,15 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines CheckerV2, used to create and register checkers.
+// This file defines Checker, used to create and register checkers.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SA_CORE_CHECKERV2
-#define LLVM_CLANG_SA_CORE_CHECKERV2
+#ifndef LLVM_CLANG_SA_CORE_CHECKER
+#define LLVM_CLANG_SA_CORE_CHECKER
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "llvm/Support/Casting.h"
namespace clang {
@@ -145,6 +146,21 @@ public:
}
};
+class Bind {
+ template <typename CHECKER>
+ static void _checkBind(void *checker, const SVal &location, const SVal &val,
+ CheckerContext &C) {
+ ((const CHECKER *)checker)->checkBind(location, val, C);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForBind(
+ CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>));
+ }
+};
+
class EndAnalysis {
template <typename CHECKER>
static void _checkEndAnalysis(void *checker, ExplodedGraph &G,
@@ -175,6 +191,22 @@ public:
}
};
+class BranchCondition {
+ template <typename CHECKER>
+ static void _checkBranchCondition(void *checker, const Stmt *condition,
+ BranchNodeBuilder &B, ExprEngine &Eng) {
+ ((const CHECKER *)checker)->checkBranchCondition(condition, B, Eng);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForBranchCondition(
+ CheckerManager::CheckBranchConditionFunc(checker,
+ _checkBranchCondition<CHECKER>));
+ }
+};
+
class LiveSymbols {
template <typename CHECKER>
static void _checkLiveSymbols(void *checker, const GRState *state,
@@ -228,10 +260,39 @@ public:
}
};
+template <typename EVENT>
+class Event {
+ template <typename CHECKER>
+ static void _checkEvent(void *checker, const void *event) {
+ ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
+ }
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerListenerForEvent<EVENT>(
+ CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
+ }
+};
+
} // end check namespace
namespace eval {
+class Assume {
+ template <typename CHECKER>
+ static const GRState *_evalAssume(void *checker, const GRState *state,
+ const SVal &cond, bool assumption) {
+ return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForEvalAssume(
+ CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
+ }
+};
+
class Call {
template <typename CHECKER>
static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) {
@@ -254,25 +315,58 @@ template <typename CHECK1, typename CHECK2=check::_VoidCheck,
typename CHECK7=check::_VoidCheck, typename CHECK8=check::_VoidCheck,
typename CHECK9=check::_VoidCheck, typename CHECK10=check::_VoidCheck,
typename CHECK11=check::_VoidCheck,typename CHECK12=check::_VoidCheck>
-class CheckerV2 {
+class Checker;
+
+template <>
+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> {
+public:
+ static void _register(void *checker, CheckerManager &mgr) { }
+};
+
+template <typename CHECK1, typename CHECK2, typename CHECK3, typename CHECK4,
+ typename CHECK5, typename CHECK6, typename CHECK7, typename CHECK8,
+ typename CHECK9, typename CHECK10,typename CHECK11,typename CHECK12>
+class Checker
+ : public CHECK1,
+ public Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7, CHECK8,
+ CHECK9, CHECK10, CHECK11, CHECK12> {
public:
template <typename CHECKER>
static void _register(CHECKER *checker, CheckerManager &mgr) {
CHECK1::_register(checker, mgr);
- CHECK2::_register(checker, mgr);
- CHECK3::_register(checker, mgr);
- CHECK4::_register(checker, mgr);
- CHECK5::_register(checker, mgr);
- CHECK6::_register(checker, mgr);
- CHECK7::_register(checker, mgr);
- CHECK8::_register(checker, mgr);
- CHECK9::_register(checker, mgr);
- CHECK10::_register(checker, mgr);
- CHECK11::_register(checker, mgr);
- CHECK12::_register(checker, mgr);
+ Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7, CHECK8, CHECK9,
+ CHECK10, CHECK11,CHECK12>::_register(checker, mgr);
+ }
+};
+
+template <typename EVENT>
+class EventDispatcher {
+ CheckerManager *Mgr;
+public:
+ EventDispatcher() : Mgr(0) { }
+
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerDispatcherForEvent<EVENT>();
+ static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
+ }
+
+ void dispatchEvent(const EVENT &event) const {
+ Mgr->_dispatchEvent(event);
}
};
+/// \brief We dereferenced a location that may be null.
+struct ImplicitNullDerefEvent {
+ SVal Location;
+ bool IsLoad;
+ ExplodedNode *SinkNode;
+ BugReporter *BR;
+};
+
} // end ento namespace
} // end clang namespace
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index 2768195..92ec038 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -37,6 +37,7 @@ namespace ento {
class ExplodedGraph;
class GRState;
class EndOfFunctionNodeBuilder;
+ class BranchNodeBuilder;
class MemRegion;
class SymbolReaper;
@@ -46,47 +47,46 @@ public:
virtual void expandGraph(ExplodedNodeSet &Dst, ExplodedNode *Pred) = 0;
};
-struct VoidCheckerFnParm {};
-template <typename P1=VoidCheckerFnParm, typename P2=VoidCheckerFnParm,
- typename P3=VoidCheckerFnParm, typename P4=VoidCheckerFnParm>
-class CheckerFn {
- typedef void (*Func)(void *, P1, P2, P3, P4);
+template <typename T> class CheckerFn;
+
+template <typename RET, typename P1, typename P2, typename P3>
+class CheckerFn<RET(P1, P2, P3)> {
+ typedef RET (*Func)(void *, P1, P2, P3);
Func Fn;
public:
void *Checker;
CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
- void operator()(P1 p1, P2 p2, P3 p3, P4 p4) { Fn(Checker, p1, p2, p3, p4); }
+ RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); }
};
-template <typename P1, typename P2, typename P3>
-class CheckerFn<P1, P2, P3, VoidCheckerFnParm> {
- typedef void (*Func)(void *, P1, P2, P3);
+template <typename RET, typename P1, typename P2>
+class CheckerFn<RET(P1, P2)> {
+ typedef RET (*Func)(void *, P1, P2);
Func Fn;
public:
void *Checker;
CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
- void operator()(P1 p1, P2 p2, P3 p3) { Fn(Checker, p1, p2, p3); }
+ RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); }
};
-template <typename P1, typename P2>
-class CheckerFn<P1, P2, VoidCheckerFnParm, VoidCheckerFnParm> {
- typedef void (*Func)(void *, P1, P2);
+template <typename RET, typename P1>
+class CheckerFn<RET(P1)> {
+ typedef RET (*Func)(void *, P1);
Func Fn;
public:
void *Checker;
CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
- void operator()(P1 p1, P2 p2) { Fn(Checker, p1, p2); }
+ RET operator()(P1 p1) const { return Fn(Checker, p1); }
};
-template <>
-class CheckerFn<VoidCheckerFnParm, VoidCheckerFnParm, VoidCheckerFnParm,
- VoidCheckerFnParm> {
- typedef void (*Func)(void *);
+template <typename RET>
+class CheckerFn<RET()> {
+ typedef RET (*Func)(void *);
Func Fn;
public:
void *Checker;
CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
- void operator()() { Fn(Checker); }
+ RET operator()() const { return Fn(Checker); }
};
class CheckerManager {
@@ -96,21 +96,35 @@ public:
CheckerManager(const LangOptions &langOpts) : LangOpts(langOpts) { }
~CheckerManager();
+ bool hasPathSensitiveCheckers() const;
+
+ void finishedCheckerRegistration();
+
const LangOptions &getLangOptions() const { return LangOpts; }
typedef void *CheckerRef;
- typedef CheckerFn<> CheckerDtor;
+ typedef void *CheckerTag;
+ typedef CheckerFn<void ()> CheckerDtor;
//===----------------------------------------------------------------------===//
// registerChecker
//===----------------------------------------------------------------------===//
/// \brief Used to register checkers.
+ ///
+ /// \returns a pointer to the checker object.
template <typename CHECKER>
- void registerChecker() {
+ CHECKER *registerChecker() {
+ CheckerTag tag = getTag<CHECKER>();
+ CheckerRef &ref = CheckerTags[tag];
+ if (ref)
+ return static_cast<CHECKER *>(ref); // already registered.
+
CHECKER *checker = new CHECKER();
CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
CHECKER::_register(checker, *this);
+ ref = checker;
+ return checker;
}
//===----------------------------------------------------------------------===//
@@ -179,6 +193,12 @@ public:
const Stmt *S,
ExprEngine &Eng);
+ /// \brief Run checkers for binding of a value to a location.
+ void runCheckersForBind(ExplodedNodeSet &Dst,
+ const ExplodedNodeSet &Src,
+ SVal location, SVal val,
+ const Stmt *S, ExprEngine &Eng);
+
/// \brief Run checkers for end of analysis.
void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
ExprEngine &Eng);
@@ -186,6 +206,10 @@ public:
/// \brief Run checkers for end of path.
void runCheckersForEndPath(EndOfFunctionNodeBuilder &B, ExprEngine &Eng);
+ /// \brief Run checkers for branch condition.
+ void runCheckersForBranchCondition(const Stmt *condition,
+ BranchNodeBuilder &B, ExprEngine &Eng);
+
/// \brief Run checkers for live symbols.
void runCheckersForLiveSymbols(const GRState *state,
SymbolReaper &SymReaper);
@@ -204,6 +228,10 @@ public:
const MemRegion * const *Begin,
const MemRegion * const *End);
+ /// \brief Run checkers for handling assumptions on symbolic values.
+ const GRState *runCheckersForEvalAssume(const GRState *state,
+ SVal Cond, bool Assumption);
+
/// \brief Run checkers for evaluating a call.
void runCheckersForEvalCall(ExplodedNodeSet &Dst,
const ExplodedNodeSet &Src,
@@ -217,9 +245,8 @@ public:
// Functions used by the registration mechanism, checkers should not touch
// these directly.
- typedef CheckerFn<const Decl *, AnalysisManager&, BugReporter &>
+ typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
CheckDeclFunc;
- typedef CheckerFn<const Stmt *, CheckerContext &> CheckStmtFunc;
typedef bool (*HandlesDeclFunc)(const Decl *D);
void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
@@ -230,14 +257,44 @@ public:
// Internal registration functions for path-sensitive checking.
//===----------------------------------------------------------------------===//
- typedef CheckerFn<const ObjCMessage &, CheckerContext &> CheckObjCMessageFunc;
- typedef CheckerFn<const SVal &/*location*/, bool/*isLoad*/, CheckerContext &>
+ typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
+
+ typedef CheckerFn<void (const ObjCMessage &, CheckerContext &)>
+ CheckObjCMessageFunc;
+
+ typedef CheckerFn<void (const SVal &location, bool isLoad, CheckerContext &)>
CheckLocationFunc;
- typedef CheckerFn<ExplodedGraph &, BugReporter &, ExprEngine &>
+
+ typedef CheckerFn<void (const SVal &location, const SVal &val,
+ CheckerContext &)> CheckBindFunc;
+
+ typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
CheckEndAnalysisFunc;
- typedef CheckerFn<EndOfFunctionNodeBuilder &, ExprEngine &> CheckEndPathFunc;
- typedef CheckerFn<SymbolReaper &, CheckerContext &> CheckDeadSymbolsFunc;
- typedef CheckerFn<const GRState *, SymbolReaper &> CheckLiveSymbolsFunc;
+
+ typedef CheckerFn<void (EndOfFunctionNodeBuilder &, ExprEngine &)>
+ CheckEndPathFunc;
+
+ typedef CheckerFn<void (const Stmt *, BranchNodeBuilder &, ExprEngine &)>
+ CheckBranchConditionFunc;
+
+ typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
+ CheckDeadSymbolsFunc;
+
+ typedef CheckerFn<void (const GRState *,SymbolReaper &)> CheckLiveSymbolsFunc;
+
+ typedef CheckerFn<const GRState * (const GRState *,
+ const MemRegion * const *begin,
+ const MemRegion * const *end)>
+ CheckRegionChangesFunc;
+
+ typedef CheckerFn<bool (const GRState *)> WantsRegionChangeUpdateFunc;
+
+ typedef CheckerFn<const GRState * (const GRState *,
+ const SVal &cond, bool assumption)>
+ EvalAssumeFunc;
+
+ typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
+ EvalCallFunc;
typedef bool (*HandlesStmtFunc)(const Stmt *D);
void _registerForPreStmt(CheckStmtFunc checkfn,
@@ -250,58 +307,55 @@ public:
void _registerForLocation(CheckLocationFunc checkfn);
+ void _registerForBind(CheckBindFunc checkfn);
+
void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
void _registerForEndPath(CheckEndPathFunc checkfn);
+ void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
+
void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
- class CheckRegionChangesFunc {
- typedef const GRState * (*Func)(void *, const GRState *,
- const MemRegion * const *,
- const MemRegion * const *);
- Func Fn;
- public:
- void *Checker;
- CheckRegionChangesFunc(void *checker, Func fn) : Fn(fn), Checker(checker) {}
- const GRState *operator()(const GRState *state,
- const MemRegion * const *begin,
- const MemRegion * const *end) {
- return Fn(Checker, state, begin, end);
- }
- };
-
- class WantsRegionChangeUpdateFunc {
- typedef bool (*Func)(void *, const GRState *);
- Func Fn;
- public:
- void *Checker;
- WantsRegionChangeUpdateFunc(void *checker, Func fn)
- : Fn(fn), Checker(checker) { }
- bool operator()(const GRState *state) {
- return Fn(Checker, state);
- }
- };
-
void _registerForRegionChanges(CheckRegionChangesFunc checkfn,
WantsRegionChangeUpdateFunc wantUpdateFn);
- class EvalCallFunc {
- typedef bool (*Func)(void *, const CallExpr *, CheckerContext &);
- Func Fn;
- public:
- void *Checker;
- EvalCallFunc(void *checker, Func fn) : Fn(fn), Checker(checker) { }
- bool operator()(const CallExpr *CE, CheckerContext &C) {
- return Fn(Checker, CE, C);
- }
- };
+ void _registerForEvalAssume(EvalAssumeFunc checkfn);
void _registerForEvalCall(EvalCallFunc checkfn);
//===----------------------------------------------------------------------===//
+// Internal registration functions for events.
+//===----------------------------------------------------------------------===//
+
+ typedef void *EventTag;
+ typedef CheckerFn<void (const void *event)> CheckEventFunc;
+
+ template <typename EVENT>
+ void _registerListenerForEvent(CheckEventFunc checkfn) {
+ EventInfo &info = Events[getTag<EVENT>()];
+ info.Checkers.push_back(checkfn);
+ }
+
+ template <typename EVENT>
+ void _registerDispatcherForEvent() {
+ EventInfo &info = Events[getTag<EVENT>()];
+ info.HasDispatcher = true;
+ }
+
+ template <typename EVENT>
+ void _dispatchEvent(const EVENT &event) const {
+ EventsTy::const_iterator I = Events.find(getTag<EVENT>());
+ if (I == Events.end())
+ return;
+ const EventInfo &info = I->second;
+ for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i)
+ info.Checkers[i](&event);
+ }
+
+//===----------------------------------------------------------------------===//
// Implementation details.
//===----------------------------------------------------------------------===//
@@ -309,6 +363,11 @@ private:
template <typename CHECKER>
static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
+ template <typename T>
+ static void *getTag() { static int tag; return &tag; }
+
+ llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
+
std::vector<CheckerDtor> CheckerDtors;
struct DeclCheckerInfo {
@@ -365,10 +424,14 @@ private:
std::vector<CheckLocationFunc> LocationCheckers;
+ std::vector<CheckBindFunc> BindCheckers;
+
std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
std::vector<CheckEndPathFunc> EndPathCheckers;
+ std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
+
std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
@@ -379,7 +442,18 @@ private:
};
std::vector<RegionChangesCheckerInfo> RegionChangesCheckers;
+ std::vector<EvalAssumeFunc> EvalAssumeCheckers;
+
std::vector<EvalCallFunc> EvalCallCheckers;
+
+ struct EventInfo {
+ llvm::SmallVector<CheckEventFunc, 4> Checkers;
+ bool HasDispatcher;
+ EventInfo() : HasDispatcher(false) { }
+ };
+
+ typedef llvm::DenseMap<EventTag, EventInfo> EventsTy;
+ EventsTy Events;
};
} // end ento namespace
diff --git a/include/clang/StaticAnalyzer/Core/CheckerProvider.h b/include/clang/StaticAnalyzer/Core/CheckerProvider.h
index 40b838e..b8aaaa1 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerProvider.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerProvider.h
@@ -15,7 +15,6 @@
#define LLVM_CLANG_SA_CORE_CHECKERPROVIDER_H
#include "llvm/ADT/StringRef.h"
-#include <vector>
namespace llvm {
class raw_ostream;
diff --git a/include/clang/StaticAnalyzer/Core/PathDiagnosticClients.h b/include/clang/StaticAnalyzer/Core/PathDiagnosticClients.h
index 2713e31..d02228f 100644
--- a/include/clang/StaticAnalyzer/Core/PathDiagnosticClients.h
+++ b/include/clang/StaticAnalyzer/Core/PathDiagnosticClients.h
@@ -12,7 +12,7 @@
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_GR_PATH_DIAGNOSTIC_CLIENTS_H
-#define LLVM_CLANG_GR_PATH_DIAGNOSTIC_CLiENTS_H
+#define LLVM_CLANG_GR_PATH_DIAGNOSTIC_CLIENTS_H
#include <string>
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
index a4327e1..65fbfcc 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
@@ -16,6 +16,7 @@
#ifndef LLVM_CLANG_GR_BASICVALUEFACTORY_H
#define LLVM_CLANG_GR_BASICVALUEFACTORY_H
+#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "clang/AST/ASTContext.h"
#include "llvm/ADT/FoldingSet.h"
@@ -47,16 +48,17 @@ public:
};
class LazyCompoundValData : public llvm::FoldingSetNode {
- const void *store;
+ StoreRef store;
const TypedRegion *region;
public:
- LazyCompoundValData(const void *st, const TypedRegion *r)
+ LazyCompoundValData(const StoreRef &st, const TypedRegion *r)
: store(st), region(r) {}
- const void *getStore() const { return store; }
+ const void *getStore() const { return store.getStore(); }
const TypedRegion *getRegion() const { return region; }
- static void Profile(llvm::FoldingSetNodeID& ID, const void *store,
+ static void Profile(llvm::FoldingSetNodeID& ID,
+ const StoreRef &store,
const TypedRegion *region);
void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, store, region); }
@@ -170,7 +172,7 @@ public:
const CompoundValData *getCompoundValData(QualType T,
llvm::ImmutableList<SVal> Vals);
- const LazyCompoundValData *getLazyCompoundValData(const void *store,
+ const LazyCompoundValData *getLazyCompoundValData(const StoreRef &store,
const TypedRegion *region);
llvm::ImmutableList<SVal> getEmptySValList() {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Checker.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Checker.h
deleted file mode 100644
index 627bc0a..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Checker.h
+++ /dev/null
@@ -1,166 +0,0 @@
-//== Checker.h - Abstract interface 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 and CheckerVisitor, classes used for creating
-// domain-specific checks.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_GR_CHECKER
-#define LLVM_CLANG_GR_CHECKER
-
-#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-
-//===----------------------------------------------------------------------===//
-// Checker interface.
-//===----------------------------------------------------------------------===//
-
-namespace clang {
-
-namespace ento {
-
-class Checker {
-private:
- friend class ExprEngine;
-
- // FIXME: Remove the 'tag' option.
- void GR_Visit(ExplodedNodeSet &Dst,
- StmtNodeBuilder &Builder,
- ExprEngine &Eng,
- const Stmt *S,
- ExplodedNode *Pred, void *tag, bool isPrevisit,
- bool& respondsToCallback) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag,
- isPrevisit ? ProgramPoint::PreStmtKind :
- ProgramPoint::PostStmtKind, &respondsToCallback, S);
- if (isPrevisit)
- _PreVisit(C, S);
- else
- _PostVisit(C, S);
- }
-
- void GR_visitObjCMessage(ExplodedNodeSet &Dst,
- StmtNodeBuilder &Builder,
- ExprEngine &Eng,
- const ObjCMessage &msg,
- ExplodedNode *Pred, void *tag, bool isPrevisit) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag,
- isPrevisit ? ProgramPoint::PreStmtKind :
- ProgramPoint::PostStmtKind, 0, msg.getOriginExpr());
- if (isPrevisit)
- preVisitObjCMessage(C, msg);
- else
- postVisitObjCMessage(C, msg);
- }
-
- bool GR_evalNilReceiver(ExplodedNodeSet &Dst, StmtNodeBuilder &Builder,
- ExprEngine &Eng, const ObjCMessage &msg,
- ExplodedNode *Pred, const GRState *state, void *tag) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
- 0, msg.getOriginExpr(), state);
- return evalNilReceiver(C, msg);
- }
-
- bool GR_evalCallExpr(ExplodedNodeSet &Dst, StmtNodeBuilder &Builder,
- ExprEngine &Eng, const CallExpr *CE,
- ExplodedNode *Pred, void *tag) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
- 0, CE);
- return evalCallExpr(C, CE);
- }
-
- // FIXME: Remove the 'tag' option.
- void GR_VisitBind(ExplodedNodeSet &Dst,
- StmtNodeBuilder &Builder, ExprEngine &Eng,
- const Stmt *StoreE, ExplodedNode *Pred, void *tag,
- SVal location, SVal val,
- bool isPrevisit) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag,
- isPrevisit ? ProgramPoint::PreStmtKind :
- ProgramPoint::PostStmtKind, 0, StoreE);
- assert(isPrevisit && "Only previsit supported for now.");
- PreVisitBind(C, StoreE, location, val);
- }
-
- // FIXME: Remove the 'tag' option.
- void GR_visitLocation(ExplodedNodeSet &Dst,
- StmtNodeBuilder &Builder,
- ExprEngine &Eng,
- const Stmt *S,
- ExplodedNode *Pred, const GRState *state,
- SVal location,
- void *tag, bool isLoad) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag,
- isLoad ? ProgramPoint::PreLoadKind :
- ProgramPoint::PreStoreKind, 0, S, state);
- visitLocation(C, S, location, isLoad);
- }
-
- void GR_evalDeadSymbols(ExplodedNodeSet &Dst, StmtNodeBuilder &Builder,
- ExprEngine &Eng, const Stmt *S, ExplodedNode *Pred,
- SymbolReaper &SymReaper, void *tag) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag,
- ProgramPoint::PostPurgeDeadSymbolsKind, 0, S);
- evalDeadSymbols(C, SymReaper);
- }
-
-public:
- virtual ~Checker();
- virtual void _PreVisit(CheckerContext &C, const Stmt *S) {}
- virtual void _PostVisit(CheckerContext &C, const Stmt *S) {}
- virtual void preVisitObjCMessage(CheckerContext &C, ObjCMessage msg) {}
- virtual void postVisitObjCMessage(CheckerContext &C, ObjCMessage msg) {}
- virtual void visitLocation(CheckerContext &C, const Stmt *S, SVal location,
- bool isLoad) {}
- virtual void PreVisitBind(CheckerContext &C, const Stmt *StoreE,
- SVal location, SVal val) {}
- virtual void evalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper) {}
- virtual void evalEndPath(EndOfFunctionNodeBuilder &B, void *tag,
- ExprEngine &Eng) {}
-
- virtual void MarkLiveSymbols(const GRState *state, SymbolReaper &SymReaper) {}
-
- virtual void VisitBranchCondition(BranchNodeBuilder &Builder,
- ExprEngine &Eng,
- const Stmt *Condition, void *tag) {}
-
- virtual bool evalNilReceiver(CheckerContext &C, ObjCMessage msg) {
- return false;
- }
-
- virtual bool evalCallExpr(CheckerContext &C, const CallExpr *CE) {
- return false;
- }
-
- virtual const GRState *evalAssume(const GRState *state, SVal Cond,
- bool Assumption, bool *respondsToCallback) {
- *respondsToCallback = false;
- return state;
- }
-
- virtual bool wantsRegionChangeUpdate(const GRState *state) { return false; }
-
- virtual const GRState *EvalRegionChanges(const GRState *state,
- const MemRegion * const *Begin,
- const MemRegion * const *End,
- bool *respondsToCallback) {
- *respondsToCallback = false;
- return state;
- }
-
- virtual void VisitEndAnalysis(ExplodedGraph &G, BugReporter &B,
- ExprEngine &Eng) {}
-};
-
-} // end GR namespace
-
-} // end clang namespace
-
-#endif
-
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.def b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.def
deleted file mode 100644
index 9b3c263..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.def
+++ /dev/null
@@ -1,48 +0,0 @@
-//===-- CheckerVisitor.def - Metadata for CheckerVisitor ----------------*-===//
-//
-// 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 AST nodes accepted by the CheckerVisitor class.
-//
-//===---------------------------------------------------------------------===//
-
-#ifndef PREVISIT
-#define PREVISIT(NODE, FALLBACK)
-#endif
-
-#ifndef POSTVISIT
-#define POSTVISIT(NODE, FALLBACK)
-#endif
-
-PREVISIT(ArraySubscriptExpr, Stmt)
-PREVISIT(BinaryOperator, Stmt)
-PREVISIT(CallExpr, GenericCall)
-PREVISIT(CompoundAssignOperator, BinaryOperator)
-PREVISIT(CStyleCastExpr, CastExpr)
-PREVISIT(CXXConstCastExpr, CastExpr)
-PREVISIT(CXXDynamicCastExpr, CastExpr)
-PREVISIT(CXXFunctionalCastExpr, CastExpr)
-PREVISIT(CXXOperatorCallExpr, GenericCall)
-PREVISIT(CXXMemberCallExpr, GenericCall)
-PREVISIT(CXXReinterpretCastExpr, CastExpr)
-PREVISIT(CXXStaticCastExpr, CastExpr)
-PREVISIT(DeclStmt, Stmt)
-PREVISIT(ImplicitCastExpr, CastExpr)
-PREVISIT(ObjCAtSynchronizedStmt, Stmt)
-PREVISIT(ReturnStmt, Stmt)
-
-POSTVISIT(BlockExpr, Stmt)
-POSTVISIT(BinaryOperator, Stmt)
-POSTVISIT(CallExpr, GenericCall)
-POSTVISIT(CompoundAssignOperator, BinaryOperator)
-POSTVISIT(CXXOperatorCallExpr, GenericCall)
-POSTVISIT(CXXMemberCallExpr, GenericCall)
-POSTVISIT(ObjCIvarRefExpr, Stmt)
-
-#undef PREVISIT
-#undef POSTVISIT
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.h
deleted file mode 100644
index dc76c96..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.h
+++ /dev/null
@@ -1,103 +0,0 @@
-//== CheckerVisitor.h - Abstract visitor 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 CheckerVisitor.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_GR_CHECKERVISITOR
-#define LLVM_CLANG_GR_CHECKERVISITOR
-#include "clang/StaticAnalyzer/Core/PathSensitive/Checker.h"
-
-namespace clang {
-
-namespace ento {
-
-//===----------------------------------------------------------------------===//
-// Checker visitor interface. Used by subclasses of Checker to specify their
-// own checker visitor logic.
-//===----------------------------------------------------------------------===//
-
-/// CheckerVisitor - This class implements a simple visitor for Stmt subclasses.
-/// Since Expr derives from Stmt, this also includes support for visiting Exprs.
-template<typename ImplClass>
-class CheckerVisitor : public Checker {
-public:
- virtual void _PreVisit(CheckerContext &C, const Stmt *S) {
- PreVisit(C, S);
- }
-
- virtual void _PostVisit(CheckerContext &C, const Stmt *S) {
- PostVisit(C, S);
- }
-
- void PreVisit(CheckerContext &C, const Stmt *S) {
- switch (S->getStmtClass()) {
- default:
- assert(false && "Unsupport statement.");
- return;
-
-#define PREVISIT(NAME, FALLBACK) \
-case Stmt::NAME ## Class:\
-static_cast<ImplClass*>(this)->PreVisit ## NAME(C,static_cast<const NAME*>(S));\
-break;
-#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.def"
- }
- }
-
- void PostVisit(CheckerContext &C, const Stmt *S) {
- switch (S->getStmtClass()) {
- default:
- assert(false && "Unsupport statement.");
- return;
-
-#define POSTVISIT(NAME, FALLBACK) \
-case Stmt::NAME ## Class:\
-static_cast<ImplClass*>(this)->\
-PostVisit ## NAME(C,static_cast<const NAME*>(S));\
-break;
-#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.def"
- }
- }
-
- void PreVisitGenericCall(CheckerContext &C, const CallExpr *CE) {
- static_cast<ImplClass*>(this)->PreVisitStmt(C, CE);
- }
- void PostVisitGenericCall(CheckerContext &C, const CallExpr *CE) {
- static_cast<ImplClass*>(this)->PostVisitStmt(C, CE);
- }
-
- void PreVisitStmt(CheckerContext &C, const Stmt *S) {
- *C.respondsToCallback = false;
- }
-
- void PostVisitStmt(CheckerContext &C, const Stmt *S) {
- *C.respondsToCallback = false;
- }
-
- void PreVisitCastExpr(CheckerContext &C, const CastExpr *E) {
- static_cast<ImplClass*>(this)->PreVisitStmt(C, E);
- }
-
-#define PREVISIT(NAME, FALLBACK) \
-void PreVisit ## NAME(CheckerContext &C, const NAME* S) {\
- static_cast<ImplClass*>(this)->PreVisit ## FALLBACK(C, S);\
-}
-#define POSTVISIT(NAME, FALLBACK) \
-void PostVisit ## NAME(CheckerContext &C, const NAME* S) {\
- static_cast<ImplClass*>(this)->PostVisit ## FALLBACK(C, S);\
-}
-#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.def"
-};
-
-} // end GR namespace
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index 25c6447..2c1d07c 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -47,7 +47,11 @@ class CoreEngine {
public:
typedef std::vector<std::pair<BlockEdge, const ExplodedNode*> >
+ BlocksExhausted;
+
+ typedef std::vector<std::pair<const CFGBlock*, const ExplodedNode*> >
BlocksAborted;
+
private:
SubEngine& SubEng;
@@ -67,6 +71,10 @@ private:
/// The locations where we stopped doing work because we visited a location
/// too many times.
+ BlocksExhausted blocksExhausted;
+
+ /// The locations where we stopped because the engine aborted analysis,
+ /// usually because it could not reason about something.
BlocksAborted blocksAborted;
void generateNode(const ProgramPoint& Loc, const GRState* State,
@@ -110,7 +118,7 @@ public:
ExplodedGraph& getGraph() { return *G.get(); }
/// takeGraph - Returns the exploded graph. Ownership of the graph is
- /// transfered to the caller.
+ /// transferred to the caller.
ExplodedGraph* takeGraph() { return G.take(); }
/// ExecuteWorkList - Run the worklist algorithm for a maximum number of
@@ -123,10 +131,25 @@ public:
// Functions for external checking of whether we have unfinished work
bool wasBlockAborted() const { return !blocksAborted.empty(); }
- bool hasWorkRemaining() const { return wasBlockAborted() || WList->hasWork(); }
-
+ bool wasBlocksExhausted() const { return !blocksExhausted.empty(); }
+ bool hasWorkRemaining() const { return wasBlocksExhausted() ||
+ WList->hasWork() ||
+ wasBlockAborted(); }
+
+ /// Inform the CoreEngine that a basic block was aborted because
+ /// it could not be completely analyzed.
+ void addAbortedBlock(const ExplodedNode *node, const CFGBlock *block) {
+ blocksAborted.push_back(std::make_pair(block, node));
+ }
+
WorkList *getWorkList() const { return WList; }
+ BlocksExhausted::const_iterator blocks_exhausted_begin() const {
+ return blocksExhausted.begin();
+ }
+ BlocksExhausted::const_iterator blocks_exhausted_end() const {
+ return blocksExhausted.end();
+ }
BlocksAborted::const_iterator blocks_aborted_begin() const {
return blocksAborted.begin();
}
@@ -219,11 +242,8 @@ public:
/// getStmt - Return the current block-level expression associated with
/// this builder.
const Stmt* getStmt() const {
- CFGStmt CS = B[Idx].getAs<CFGStmt>();
- if (CS)
- return CS.getStmt();
- else
- return 0;
+ const CFGStmt *CS = B[Idx].getAs<CFGStmt>();
+ return CS ? CS->getStmt() : 0;
}
/// getBlock - Return the CFGBlock associated with the block-level expression
@@ -287,6 +307,8 @@ public:
BlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
+ ExplodedNode* generateNode(const Stmt *Condition, const GRState* State);
+
ExplodedNode* generateNode(const GRState* State, bool branch);
const CFGBlock* getTargetBlock(bool branch) const {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
index 732a40cb..193056e 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
@@ -51,9 +51,10 @@ public:
iterator end() const { return ExprBindings.end(); }
- /// GetSVal - Fetches the current binding of the expression in the
+ /// getSVal - Fetches the current binding of the expression in the
/// Environment.
- SVal getSVal(const Stmt* Ex, SValBuilder& svalBuilder) const;
+ SVal getSVal(const Stmt* Ex, SValBuilder& svalBuilder,
+ bool useOnlyDirectBindings = false) const;
/// Profile - Profile the contents of an Environment object for use
/// in a FoldingSet.
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 16f54ee..8cd743f 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -34,7 +34,6 @@ class ObjCForCollectionStmt;
namespace ento {
class AnalysisManager;
-class Checker;
class ExprEngine : public SubEngine {
AnalysisManager &AMgr;
@@ -74,39 +73,6 @@ class ExprEngine : public SubEngine {
Selector* NSExceptionInstanceRaiseSelectors;
Selector RaiseSel;
- enum CallbackKind {
- PreVisitStmtCallback,
- PostVisitStmtCallback,
- processAssumeCallback,
- EvalRegionChangesCallback
- };
-
- typedef uint32_t CallbackTag;
-
- /// GetCallbackTag - Create a tag for a certain kind of callback. The 'Sub'
- /// argument can be used to differentiate callbacks that depend on another
- /// value from a small set of possibilities, such as statement classes.
- static inline CallbackTag GetCallbackTag(CallbackKind K, uint32_t Sub = 0) {
- assert(Sub == ((Sub << 8) >> 8) && "Tag sub-kind must fit into 24 bits");
- return K | (Sub << 8);
- }
-
- typedef llvm::DenseMap<void *, unsigned> CheckerMap;
- typedef std::vector<std::pair<void *, Checker*> > CheckersOrdered;
- typedef llvm::DenseMap<CallbackTag, CheckersOrdered *> CheckersOrderedCache;
-
- /// A registration map from checker tag to the index into the
- /// ordered checkers vector.
- CheckerMap CheckerM;
-
- /// An ordered vector of checkers that are called when evaluating
- /// various expressions and statements.
- CheckersOrdered Checkers;
-
- /// A map used for caching the checkers that respond to the callback for
- /// a particular callback tag.
- CheckersOrderedCache COCache;
-
/// The BugReporter associated with this engine. It is important that
/// this object be placed at the very end of member variables so that its
/// destructor is called before the rest of the ExprEngine is destroyed.
@@ -165,21 +131,6 @@ public:
ExplodedGraph& getGraph() { return G; }
const ExplodedGraph& getGraph() const { return G; }
- template <typename CHECKER>
- void registerCheck(CHECKER *check) {
- unsigned entry = Checkers.size();
- void *tag = CHECKER::getTag();
- Checkers.push_back(std::make_pair(tag, check));
- CheckerM[tag] = entry;
- }
-
- Checker *lookupChecker(void *tag) const;
-
- template <typename CHECKER>
- CHECKER *getChecker() const {
- return static_cast<CHECKER*>(lookupChecker(CHECKER::getTag()));
- }
-
/// processCFGElement - Called by CoreEngine. Used to generate new successor
/// nodes by processing the 'effects' of a CFG element.
void processCFGElement(const CFGElement E, StmtNodeBuilder& builder);
@@ -262,11 +213,9 @@ public:
const SymbolManager& getSymbolManager() const { return SymMgr; }
// Functions for external checking of whether we have unfinished work
- bool wasBlockAborted() const { return Engine.wasBlockAborted(); }
+ bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); }
bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); }
- bool hasWorkRemaining() const {
- return wasBlockAborted() || Engine.getWorkList()->hasWork();
- }
+ bool hasWorkRemaining() const { return Engine.hasWorkRemaining(); }
const CoreEngine &getCoreEngine() const { return Engine; }
@@ -281,27 +230,6 @@ public:
ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
const void *tag = 0);
- /// CheckerVisit - Dispatcher for performing checker-specific logic
- /// at specific statements.
- void CheckerVisit(const Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
- CallbackKind Kind);
-
- void CheckerVisitObjCMessage(const ObjCMessage &msg, ExplodedNodeSet &Dst,
- ExplodedNodeSet &Src, bool isPrevisit);
-
- bool CheckerEvalCall(const CallExpr *CE,
- ExplodedNodeSet &Dst,
- ExplodedNode *Pred);
-
- void CheckerEvalNilReceiver(const ObjCMessage &msg,
- ExplodedNodeSet &Dst,
- const GRState *state,
- ExplodedNode *Pred);
-
- void CheckerVisitBind(const Stmt *StoreE, ExplodedNodeSet &Dst,
- ExplodedNodeSet &Src, SVal location, SVal val,
- bool isPrevisit);
-
/// Visit - Transfer function logic for all statements. Dispatches to
/// other functions that handle specific kinds of statements.
void Visit(const Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst);
@@ -334,10 +262,8 @@ public:
/// VisitCall - Transfer function for function calls.
- void VisitCall(const CallExpr* CE, ExplodedNode* Pred,
- CallExpr::const_arg_iterator AI,
- CallExpr::const_arg_iterator AE,
- ExplodedNodeSet& Dst);
+ void VisitCallExpr(const CallExpr* CE, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst);
/// VisitCast - Transfer function logic for all casts (implicit and explicit).
void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred,
@@ -358,11 +284,6 @@ public:
/// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose
void VisitGuardedExpr(const Expr* Ex, const Expr* L, const Expr* R,
ExplodedNode* Pred, ExplodedNodeSet& Dst);
-
- /// VisitCondInit - Transfer function for handling the initialization
- /// of a condition variable in an IfStmt, SwitchStmt, etc.
- void VisitCondInit(const VarDecl *VD, const Stmt *S, ExplodedNode *Pred,
- ExplodedNodeSet& Dst);
void VisitInitListExpr(const InitListExpr* E, ExplodedNode* Pred,
ExplodedNodeSet& Dst);
@@ -409,9 +330,9 @@ public:
void VisitOffsetOfExpr(const OffsetOfExpr* Ex, ExplodedNode* Pred,
ExplodedNodeSet& Dst);
- /// VisitSizeOfAlignOfExpr - Transfer function for sizeof.
- void VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr* Ex, ExplodedNode* Pred,
- ExplodedNodeSet& Dst);
+ /// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
+ void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr* Ex,
+ ExplodedNode* Pred, ExplodedNodeSet& Dst);
/// VisitUnaryOperator - Transfer function logic for unary operators.
void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode* Pred,
@@ -432,12 +353,6 @@ public:
const MemRegion *Dest, const Stmt *S,
ExplodedNode *Pred, ExplodedNodeSet &Dst);
- void VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *C,
- ExplodedNode *Pred, ExplodedNodeSet &Dst);
-
void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
ExplodedNodeSet &Dst);
@@ -463,12 +378,10 @@ public:
const FunctionProtoType *FnType,
ExplodedNode *Pred, ExplodedNodeSet &Dst,
bool FstArgAsLValue = false);
-
- /// Evaluate method call itself. Used for CXXMethodCallExpr and
- /// CXXOperatorCallExpr.
- void evalMethodCall(const CallExpr *MCE, const CXXMethodDecl *MD,
- const Expr *ThisExpr, ExplodedNode *Pred,
- ExplodedNodeSet &Src, ExplodedNodeSet &Dst);
+
+ /// Evaluate callee expression (for a function call).
+ void evalCallee(const CallExpr *callExpr, const ExplodedNodeSet &src,
+ ExplodedNodeSet &dest);
/// evalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic
/// expressions of the form 'x != 0' and generate new nodes (stored in Dst)
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h
index 37694da..a957c89 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h
@@ -35,7 +35,6 @@ class ASTContext;
namespace ento {
class GRStateManager;
-class Checker;
typedef ConstraintManager* (*ConstraintManagerCreator)(GRStateManager&,
SubEngine&);
@@ -261,7 +260,7 @@ public:
const llvm::APSInt *getSymVal(SymbolRef sym) const;
/// Returns the SVal bound to the statement 'S' in the state's environment.
- SVal getSVal(const Stmt* S) const;
+ SVal getSVal(const Stmt* S, bool useOnlyDirectBindings = false) const;
SVal getSValAsScalarOrLoc(const Stmt *Ex) const;
@@ -274,8 +273,6 @@ public:
SVal getSValAsScalarOrLoc(const MemRegion *R) const;
- const llvm::APSInt *getSymVal(SymbolRef sym);
-
bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const;
bool scanReachableSymbols(const SVal *I, const SVal *E,
@@ -627,10 +624,6 @@ public:
// Out-of-line method definitions for GRState.
//===----------------------------------------------------------------------===//
-inline const llvm::APSInt *GRState::getSymVal(SymbolRef sym) {
- return getStateManager().getSymVal(this, sym);
-}
-
inline const VarRegion* GRState::getRegion(const VarDecl *D,
const LocationContext *LC) const {
return getStateManager().getRegionManager().getVarRegion(D, LC);
@@ -690,14 +683,15 @@ inline const llvm::APSInt *GRState::getSymVal(SymbolRef sym) const {
return getStateManager().getSymVal(this, sym);
}
-inline SVal GRState::getSVal(const Stmt* Ex) const {
- return Env.getSVal(Ex, *getStateManager().svalBuilder);
+inline SVal GRState::getSVal(const Stmt* Ex, bool useOnlyDirectBindings) const{
+ return Env.getSVal(Ex, *getStateManager().svalBuilder,
+ useOnlyDirectBindings);
}
inline SVal GRState::getSValAsScalarOrLoc(const Stmt *S) const {
if (const Expr *Ex = dyn_cast<Expr>(S)) {
QualType T = Ex->getType();
- if (Loc::isLocType(T) || T->isIntegerType())
+ if (Ex->isLValue() || Loc::isLocType(T) || T->isIntegerType())
return getSVal(S);
}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index 8d19b51..db7a930 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -769,7 +769,7 @@ public:
}
};
//===----------------------------------------------------------------------===//
-// Auxillary data classes for use with MemRegions.
+// Auxiliary data classes for use with MemRegions.
//===----------------------------------------------------------------------===//
class ElementRegion;
@@ -960,7 +960,7 @@ public:
getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
const LocationContext *LC);
- /// getCXXThisRegion - Retrieve the [artifical] region associated with the
+ /// getCXXThisRegion - Retrieve the [artificial] region associated with the
/// parameter 'this'.
const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
const LocationContext *LC);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h
index 710fc6b..6d8fc89 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h
@@ -72,6 +72,8 @@ public:
return getType(ctx);
}
+ ObjCMethodFamily getMethodFamily() const;
+
Selector getSelector() const;
const Expr *getInstanceReceiver() const {
@@ -169,14 +171,23 @@ class CallOrObjCMessage {
const CallExpr *CallE;
ObjCMessage Msg;
const GRState *State;
-
public:
CallOrObjCMessage(const CallExpr *callE, const GRState *state)
- : CallE(callE), State(state) { }
+ : CallE(callE), State(state) {}
CallOrObjCMessage(const ObjCMessage &msg, const GRState *state)
- : CallE(0), Msg(msg), State(state) { }
+ : CallE(0), Msg(msg), State(state) {}
QualType getResultType(ASTContext &ctx) const;
+
+ bool isFunctionCall() const {
+ return (bool) CallE;
+ }
+
+ bool isCXXCall() const {
+ return CallE && isa<CXXMemberCallExpr>(CallE);
+ }
+
+ SVal getCXXCallee() const;
unsigned getNumArgs() const {
if (CallE) return CallE->getNumArgs();
@@ -185,7 +196,8 @@ public:
SVal getArgSVal(unsigned i) const {
assert(i < getNumArgs());
- if (CallE) return State->getSVal(CallE->getArg(i));
+ if (CallE)
+ return State->getSVal(CallE->getArg(i));
return Msg.getArgSVal(i, State);
}
@@ -193,13 +205,15 @@ public:
const Expr *getArg(unsigned i) const {
assert(i < getNumArgs());
- if (CallE) return CallE->getArg(i);
+ if (CallE)
+ return CallE->getArg(i);
return Msg.getArgExpr(i);
}
SourceRange getArgSourceRange(unsigned i) const {
assert(i < getNumArgs());
- if (CallE) return CallE->getArg(i)->getSourceRange();
+ if (CallE)
+ return CallE->getArg(i)->getSourceRange();
return Msg.getArgSourceRange(i);
}
};
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index fc2b76e..0f9e56a 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -49,10 +49,10 @@ protected:
const unsigned ArrayIndexWidth;
public:
- // FIXME: Make these protected again one RegionStoreManager correctly
- // handles loads from differening bound value types.
- virtual SVal evalCastNL(NonLoc val, QualType castTy) = 0;
- virtual SVal evalCastL(Loc val, QualType castTy) = 0;
+ // FIXME: Make these protected again once RegionStoreManager correctly
+ // handles loads from different bound value types.
+ virtual SVal evalCastFromNonLoc(NonLoc val, QualType castTy) = 0;
+ virtual SVal evalCastFromLoc(Loc val, QualType castTy) = 0;
public:
SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context,
@@ -66,30 +66,30 @@ public:
virtual ~SValBuilder() {}
- SVal evalCast(SVal V, QualType castTy, QualType originalType);
+ SVal evalCast(SVal val, QualType castTy, QualType originalType);
virtual SVal evalMinus(NonLoc val) = 0;
virtual SVal evalComplement(NonLoc val) = 0;
- virtual SVal evalBinOpNN(const GRState *state, BinaryOperator::Opcode Op,
+ virtual SVal evalBinOpNN(const GRState *state, BinaryOperator::Opcode op,
NonLoc lhs, NonLoc rhs, QualType resultTy) = 0;
- virtual SVal evalBinOpLL(const GRState *state, BinaryOperator::Opcode Op,
+ virtual SVal evalBinOpLL(const GRState *state, BinaryOperator::Opcode op,
Loc lhs, Loc rhs, QualType resultTy) = 0;
- virtual SVal evalBinOpLN(const GRState *state, BinaryOperator::Opcode Op,
+ virtual SVal evalBinOpLN(const GRState *state, BinaryOperator::Opcode op,
Loc lhs, NonLoc rhs, QualType resultTy) = 0;
/// getKnownValue - evaluates a given SVal. If the SVal has only one possible
/// (integer) value, that value is returned. Otherwise, returns NULL.
- virtual const llvm::APSInt *getKnownValue(const GRState *state, SVal V) = 0;
+ virtual const llvm::APSInt *getKnownValue(const GRState *state, SVal val) = 0;
- SVal evalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
- SVal L, SVal R, QualType T);
+ SVal evalBinOp(const GRState *state, BinaryOperator::Opcode op,
+ SVal lhs, SVal rhs, QualType type);
- DefinedOrUnknownSVal evalEQ(const GRState *ST, DefinedOrUnknownSVal L,
- DefinedOrUnknownSVal R);
+ DefinedOrUnknownSVal evalEQ(const GRState *state, DefinedOrUnknownSVal lhs,
+ DefinedOrUnknownSVal rhs);
ASTContext &getContext() { return Context; }
const ASTContext &getContext() const { return Context; }
@@ -115,46 +115,48 @@ public:
// Forwarding methods to SymbolManager.
- const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T,
- unsigned VisitCount,
- const void* SymbolTag = 0) {
- return SymMgr.getConjuredSymbol(E, T, VisitCount, SymbolTag);
+ const SymbolConjured* getConjuredSymbol(const Stmt* stmt, QualType type,
+ unsigned visitCount,
+ const void* symbolTag = 0) {
+ return SymMgr.getConjuredSymbol(stmt, type, visitCount, symbolTag);
}
- const SymbolConjured* getConjuredSymbol(const Expr* E, unsigned VisitCount,
- const void* SymbolTag = 0) {
- return SymMgr.getConjuredSymbol(E, VisitCount, SymbolTag);
+ const SymbolConjured* getConjuredSymbol(const Expr* expr, unsigned visitCount,
+ const void* symbolTag = 0) {
+ return SymMgr.getConjuredSymbol(expr, visitCount, symbolTag);
}
/// makeZeroVal - Construct an SVal representing '0' for the specified type.
- DefinedOrUnknownSVal makeZeroVal(QualType T);
+ DefinedOrUnknownSVal makeZeroVal(QualType type);
- /// getRegionValueSymbolVal - make a unique symbol for value of R.
- DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedRegion *R);
+ /// getRegionValueSymbolVal - make a unique symbol for value of region.
+ DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedRegion *region);
- DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag,
- const Expr *E, unsigned Count);
- DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag,
- const Expr *E, QualType T,
- unsigned Count);
+ DefinedOrUnknownSVal getConjuredSymbolVal(const void *symbolTag,
+ const Expr *expr, unsigned count);
+ DefinedOrUnknownSVal getConjuredSymbolVal(const void *symbolTag,
+ const Expr *expr, QualType type,
+ unsigned count);
- DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
- const TypedRegion *R);
+ DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(
+ SymbolRef parentSymbol, const TypedRegion *region);
- DefinedSVal getMetadataSymbolVal(const void *SymbolTag, const MemRegion *MR,
- const Expr *E, QualType T, unsigned Count);
+ DefinedSVal getMetadataSymbolVal(
+ const void *symbolTag, const MemRegion *region,
+ const Expr *expr, QualType type, unsigned count);
- DefinedSVal getFunctionPointer(const FunctionDecl *FD);
+ DefinedSVal getFunctionPointer(const FunctionDecl *func);
- DefinedSVal getBlockPointer(const BlockDecl *BD, CanQualType locTy,
- const LocationContext *LC);
+ DefinedSVal getBlockPointer(const BlockDecl *block, CanQualType locTy,
+ const LocationContext *locContext);
- NonLoc makeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals) {
- return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
+ NonLoc makeCompoundVal(QualType type, llvm::ImmutableList<SVal> vals) {
+ return nonloc::CompoundVal(BasicVals.getCompoundValData(type, vals));
}
- NonLoc makeLazyCompoundVal(const void *store, const TypedRegion *R) {
- return nonloc::LazyCompoundVal(BasicVals.getLazyCompoundValData(store, R));
+ NonLoc makeLazyCompoundVal(const StoreRef &store, const TypedRegion *region) {
+ return nonloc::LazyCompoundVal(
+ BasicVals.getLazyCompoundValData(store, region));
}
NonLoc makeZeroArrayIndex() {
@@ -165,60 +167,63 @@ public:
return nonloc::ConcreteInt(BasicVals.getValue(idx, ArrayIndexTy));
}
- SVal convertToArrayIndex(SVal V);
+ SVal convertToArrayIndex(SVal val);
- nonloc::ConcreteInt makeIntVal(const IntegerLiteral* I) {
- return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(),
- I->getType()->isUnsignedIntegerType()));
+ nonloc::ConcreteInt makeIntVal(const IntegerLiteral* integer) {
+ return nonloc::ConcreteInt(
+ BasicVals.getValue(integer->getValue(),
+ integer->getType()->isUnsignedIntegerType()));
}
- nonloc::ConcreteInt makeBoolVal(const CXXBoolLiteralExpr *E) {
- return makeTruthVal(E->getValue());
+ nonloc::ConcreteInt makeBoolVal(const CXXBoolLiteralExpr *boolean) {
+ return makeTruthVal(boolean->getValue());
}
- nonloc::ConcreteInt makeIntVal(const llvm::APSInt& V) {
- return nonloc::ConcreteInt(BasicVals.getValue(V));
+ nonloc::ConcreteInt makeIntVal(const llvm::APSInt& integer) {
+ return nonloc::ConcreteInt(BasicVals.getValue(integer));
}
- loc::ConcreteInt makeIntLocVal(const llvm::APSInt &v) {
- return loc::ConcreteInt(BasicVals.getValue(v));
+ loc::ConcreteInt makeIntLocVal(const llvm::APSInt &integer) {
+ return loc::ConcreteInt(BasicVals.getValue(integer));
}
- NonLoc makeIntVal(const llvm::APInt& V, bool isUnsigned) {
- return nonloc::ConcreteInt(BasicVals.getValue(V, isUnsigned));
+ NonLoc makeIntVal(const llvm::APInt& integer, bool isUnsigned) {
+ return nonloc::ConcreteInt(BasicVals.getValue(integer, isUnsigned));
}
- DefinedSVal makeIntVal(uint64_t X, QualType T) {
- if (Loc::isLocType(T))
- return loc::ConcreteInt(BasicVals.getValue(X, T));
+ DefinedSVal makeIntVal(uint64_t integer, QualType type) {
+ if (Loc::isLocType(type))
+ return loc::ConcreteInt(BasicVals.getValue(integer, type));
- return nonloc::ConcreteInt(BasicVals.getValue(X, T));
+ return nonloc::ConcreteInt(BasicVals.getValue(integer, type));
}
- NonLoc makeIntVal(uint64_t X, bool isUnsigned) {
- return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned));
+ NonLoc makeIntVal(uint64_t integer, bool isUnsigned) {
+ return nonloc::ConcreteInt(BasicVals.getIntValue(integer, isUnsigned));
}
- NonLoc makeIntValWithPtrWidth(uint64_t X, bool isUnsigned) {
- return nonloc::ConcreteInt(BasicVals.getIntWithPtrWidth(X, isUnsigned));
+ NonLoc makeIntValWithPtrWidth(uint64_t integer, bool isUnsigned) {
+ return nonloc::ConcreteInt(
+ BasicVals.getIntWithPtrWidth(integer, isUnsigned));
}
- NonLoc makeIntVal(uint64_t X, unsigned BitWidth, bool isUnsigned) {
- return nonloc::ConcreteInt(BasicVals.getValue(X, BitWidth, isUnsigned));
+ NonLoc makeIntVal(uint64_t integer, unsigned bitWidth, bool isUnsigned) {
+ return nonloc::ConcreteInt(
+ BasicVals.getValue(integer, bitWidth, isUnsigned));
}
- NonLoc makeLocAsInteger(Loc V, unsigned Bits) {
- return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(V, Bits));
+ NonLoc makeLocAsInteger(Loc loc, unsigned bits) {
+ return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(loc, bits));
}
NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
- const llvm::APSInt& rhs, QualType T);
+ const llvm::APSInt& rhs, QualType type);
NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
- const SymExpr *rhs, QualType T);
+ const SymExpr *rhs, QualType type);
- nonloc::ConcreteInt makeTruthVal(bool b, QualType T) {
- return nonloc::ConcreteInt(BasicVals.getTruthValue(b, T));
+ nonloc::ConcreteInt makeTruthVal(bool b, QualType type) {
+ return nonloc::ConcreteInt(BasicVals.getTruthValue(b, type));
}
nonloc::ConcreteInt makeTruthVal(bool b) {
@@ -229,20 +234,20 @@ public:
return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth());
}
- Loc makeLoc(SymbolRef Sym) {
- return loc::MemRegionVal(MemMgr.getSymbolicRegion(Sym));
+ Loc makeLoc(SymbolRef sym) {
+ return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
}
- Loc makeLoc(const MemRegion* R) {
- return loc::MemRegionVal(R);
+ Loc makeLoc(const MemRegion* region) {
+ return loc::MemRegionVal(region);
}
- Loc makeLoc(const AddrLabelExpr *E) {
- return loc::GotoLabel(E->getLabel());
+ Loc makeLoc(const AddrLabelExpr *expr) {
+ return loc::GotoLabel(expr->getLabel());
}
- Loc makeLoc(const llvm::APSInt& V) {
- return loc::ConcreteInt(BasicVals.getValue(V));
+ Loc makeLoc(const llvm::APSInt& integer) {
+ return loc::ConcreteInt(BasicVals.getValue(integer));
}
};
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
index 0251311..21c6ae7 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_GR_STORE_H
#define LLVM_CLANG_GR_STORE_H
+#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
#include "llvm/ADT/DenseSet.h"
@@ -28,36 +29,10 @@ class StackFrameContext;
namespace ento {
-/// Store - This opaque type encapsulates an immutable mapping from
-/// locations to values. At a high-level, it represents the symbolic
-/// memory model. Different subclasses of StoreManager may choose
-/// different types to represent the locations and values.
-typedef const void* Store;
-
class GRState;
class GRStateManager;
class SubRegionMap;
-class StoreManager;
-
-class StoreRef {
- Store store;
- StoreManager &mgr;
-public:
- StoreRef(Store, StoreManager &);
- StoreRef(const StoreRef &);
- StoreRef &operator=(StoreRef const &);
-
- bool operator==(const StoreRef &x) const {
- assert(&mgr == &x.mgr);
- return x.store == store;
- }
- bool operator!=(const StoreRef &x) const { return !operator==(x); }
- ~StoreRef();
-
- Store getStore() const { return store; }
-};
-
class StoreManager {
protected:
SValBuilder &svalBuilder;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h b/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h
new file mode 100644
index 0000000..0662ead
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h
@@ -0,0 +1,50 @@
+//== StoreRef.h - Smart pointer for store objects ---------------*- C++ -*--==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defined the type StoreRef.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_STOREREF_H
+#define LLVM_CLANG_GR_STOREREF_H
+
+#include <cassert>
+
+namespace clang {
+namespace ento {
+
+/// Store - This opaque type encapsulates an immutable mapping from
+/// locations to values. At a high-level, it represents the symbolic
+/// memory model. Different subclasses of StoreManager may choose
+/// different types to represent the locations and values.
+typedef const void* Store;
+
+class StoreManager;
+
+class StoreRef {
+ Store store;
+ StoreManager &mgr;
+public:
+ StoreRef(Store, StoreManager &);
+ StoreRef(const StoreRef &);
+ StoreRef &operator=(StoreRef const &);
+
+ bool operator==(const StoreRef &x) const {
+ assert(&mgr == &x.mgr);
+ return x.store == store;
+ }
+ bool operator!=(const StoreRef &x) const { return !operator==(x); }
+
+ ~StoreRef();
+
+ Store getStore() const { return store; }
+};
+
+}}
+#endif
OpenPOWER on IntegriCloud