summaryrefslogtreecommitdiff
path: root/include/clang/StaticAnalyzer/Core/PathSensitive
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/StaticAnalyzer/Core/PathSensitive')
-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
13 files changed, 209 insertions, 550 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
index a4327e127f5fe..65fbfcc912f92 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 627bc0ab3516d..0000000000000
--- 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 9b3c263e7d53b..0000000000000
--- 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 dc76c96047419..0000000000000
--- 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 25c6447342329..2c1d07c59b688 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 732a40cb21455..193056e6b0305 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 16f54ee7468da..8cd743f68f567 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 37694da6573c5..a957c897b92ae 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 8d19b51992746..db7a930b556eb 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 710fc6b84f9e7..6d8fc89a4839e 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 fc2b76e04a66a..0f9e56aa2ff88 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 0251311c27ae4..21c6ae760cc8d 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 0000000000000..0662eadc93c33
--- /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