diff options
author | dim <dim@FreeBSD.org> | 2011-02-20 13:06:31 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-02-20 13:06:31 +0000 |
commit | 39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df (patch) | |
tree | a9243275843fbeaa590afc07ee888e006b8d54ea /include/clang/Checker/PathSensitive | |
parent | 69b4eca4a4255ba43baa5c1d9bbdec3ec17f479e (diff) | |
download | FreeBSD-src-39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df.zip FreeBSD-src-39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df.tar.gz |
Vendor import of clang trunk r126079:
http://llvm.org/svn/llvm-project/cfe/trunk@126079
Diffstat (limited to 'include/clang/Checker/PathSensitive')
27 files changed, 0 insertions, 6549 deletions
diff --git a/include/clang/Checker/PathSensitive/AnalysisManager.h b/include/clang/Checker/PathSensitive/AnalysisManager.h deleted file mode 100644 index 3855079..0000000 --- a/include/clang/Checker/PathSensitive/AnalysisManager.h +++ /dev/null @@ -1,202 +0,0 @@ -//== AnalysisManager.h - Path sensitive analysis data manager ------*- C++ -*-// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the AnalysisManager class that manages the data and policy -// for path sensitive analysis. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_ANALYSISMANAGER_H -#define LLVM_CLANG_ANALYSIS_ANALYSISMANAGER_H - -#include "clang/Analysis/AnalysisContext.h" -#include "clang/Checker/BugReporter/BugReporter.h" -#include "clang/Checker/BugReporter/PathDiagnostic.h" - -namespace clang { - -namespace idx { - class Indexer; - class TranslationUnit; -} - -class AnalysisManager : public BugReporterData { - AnalysisContextManager AnaCtxMgr; - LocationContextManager LocCtxMgr; - - ASTContext &Ctx; - Diagnostic &Diags; - const LangOptions &LangInfo; - - llvm::OwningPtr<PathDiagnosticClient> PD; - - // Configurable components creators. - StoreManagerCreator CreateStoreMgr; - ConstraintManagerCreator CreateConstraintMgr; - - /// \brief Provide function definitions in other translation units. This is - /// NULL if we don't have multiple translation units. AnalysisManager does - /// not own the Indexer. - idx::Indexer *Idxer; - - enum AnalysisScope { ScopeTU, ScopeDecl } AScope; - - // The maximum number of exploded nodes the analyzer will generate. - unsigned MaxNodes; - - // The maximum number of times the analyzer will go through a loop. - unsigned MaxLoop; - - bool VisualizeEGDot; - bool VisualizeEGUbi; - bool PurgeDead; - - /// EargerlyAssume - A flag indicating how the engine should handle - // expressions such as: 'x = (y != 0)'. When this flag is true then - // the subexpression 'y != 0' will be eagerly assumed to be true or false, - // thus evaluating it to the integers 0 or 1 respectively. The upside - // is that this can increase analysis precision until we have a better way - // to lazily evaluate such logic. The downside is that it eagerly - // bifurcates paths. - bool EagerlyAssume; - bool TrimGraph; - bool InlineCall; - -public: - AnalysisManager(ASTContext &ctx, Diagnostic &diags, - const LangOptions &lang, PathDiagnosticClient *pd, - StoreManagerCreator storemgr, - ConstraintManagerCreator constraintmgr, - idx::Indexer *idxer, - unsigned maxnodes, unsigned maxloop, - bool vizdot, bool vizubi, bool purge, bool eager, bool trim, - bool inlinecall, bool useUnoptimizedCFG) - - : AnaCtxMgr(useUnoptimizedCFG), Ctx(ctx), Diags(diags), LangInfo(lang), - PD(pd), - CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),Idxer(idxer), - AScope(ScopeDecl), MaxNodes(maxnodes), MaxLoop(maxloop), - VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge), - EagerlyAssume(eager), TrimGraph(trim), InlineCall(inlinecall) {} - - ~AnalysisManager() { FlushDiagnostics(); } - - void ClearContexts() { - LocCtxMgr.clear(); - AnaCtxMgr.clear(); - } - - AnalysisContextManager& getAnalysisContextManager() { - return AnaCtxMgr; - } - - StoreManagerCreator getStoreManagerCreator() { - return CreateStoreMgr; - } - - ConstraintManagerCreator getConstraintManagerCreator() { - return CreateConstraintMgr; - } - - idx::Indexer *getIndexer() const { return Idxer; } - - virtual ASTContext &getASTContext() { - return Ctx; - } - - virtual SourceManager &getSourceManager() { - return getASTContext().getSourceManager(); - } - - virtual Diagnostic &getDiagnostic() { - return Diags; - } - - const LangOptions &getLangOptions() const { - return LangInfo; - } - - virtual PathDiagnosticClient *getPathDiagnosticClient() { - return PD.get(); - } - - void FlushDiagnostics() { - if (PD.get()) - PD->FlushDiagnostics(); - } - - unsigned getMaxNodes() const { return MaxNodes; } - - unsigned getMaxLoop() const { return MaxLoop; } - - bool shouldVisualizeGraphviz() const { return VisualizeEGDot; } - - bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; } - - bool shouldVisualize() const { - return VisualizeEGDot || VisualizeEGUbi; - } - - bool shouldTrimGraph() const { return TrimGraph; } - - bool shouldPurgeDead() const { return PurgeDead; } - - bool shouldEagerlyAssume() const { return EagerlyAssume; } - - bool shouldInlineCall() const { return InlineCall; } - - bool hasIndexer() const { return Idxer != 0; } - - const AnalysisContext *getAnalysisContextInAnotherTU(const Decl *D); - - CFG *getCFG(Decl const *D) { - return AnaCtxMgr.getContext(D)->getCFG(); - } - - LiveVariables *getLiveVariables(Decl const *D) { - return AnaCtxMgr.getContext(D)->getLiveVariables(); - } - - ParentMap &getParentMap(Decl const *D) { - return AnaCtxMgr.getContext(D)->getParentMap(); - } - - AnalysisContext *getAnalysisContext(const Decl *D) { - return AnaCtxMgr.getContext(D); - } - - AnalysisContext *getAnalysisContext(const Decl *D, idx::TranslationUnit *TU) { - return AnaCtxMgr.getContext(D, TU); - } - - const StackFrameContext *getStackFrame(AnalysisContext *Ctx, - LocationContext const *Parent, - Stmt const *S, const CFGBlock *Blk, - unsigned Idx) { - return LocCtxMgr.getStackFrame(Ctx, Parent, S, Blk, Idx); - } - - // Get the top level stack frame. - const StackFrameContext *getStackFrame(Decl const *D, - idx::TranslationUnit *TU) { - return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D, TU), 0, 0, 0, 0); - } - - // Get a stack frame with parent. - StackFrameContext const *getStackFrame(Decl const *D, - LocationContext const *Parent, - Stmt const *S, const CFGBlock *Blk, - unsigned Idx) { - return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), Parent, S, Blk,Idx); - } -}; - -} - -#endif diff --git a/include/clang/Checker/PathSensitive/BasicValueFactory.h b/include/clang/Checker/PathSensitive/BasicValueFactory.h deleted file mode 100644 index 59dd919..0000000 --- a/include/clang/Checker/PathSensitive/BasicValueFactory.h +++ /dev/null @@ -1,197 +0,0 @@ -//=== BasicValueFactory.h - Basic values for Path Sens analysis --*- C++ -*---// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines BasicValueFactory, a class that manages the lifetime -// of APSInt objects and symbolic constraints used by GRExprEngine -// and related classes. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H -#define LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H - -#include "clang/Checker/PathSensitive/SVals.h" -#include "clang/AST/ASTContext.h" -#include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/APSInt.h" -#include "llvm/ADT/ImmutableList.h" - -namespace clang { - - class GRState; - -class CompoundValData : public llvm::FoldingSetNode { - QualType T; - llvm::ImmutableList<SVal> L; - -public: - CompoundValData(QualType t, llvm::ImmutableList<SVal> l) - : T(t), L(l) {} - - typedef llvm::ImmutableList<SVal>::iterator iterator; - iterator begin() const { return L.begin(); } - iterator end() const { return L.end(); } - - static void Profile(llvm::FoldingSetNodeID& ID, QualType T, - llvm::ImmutableList<SVal> L); - - void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, T, L); } -}; - -class LazyCompoundValData : public llvm::FoldingSetNode { - const void *store; - const TypedRegion *region; -public: - LazyCompoundValData(const void *st, const TypedRegion *r) - : store(st), region(r) {} - - const void *getStore() const { return store; } - const TypedRegion *getRegion() const { return region; } - - static void Profile(llvm::FoldingSetNodeID& ID, const void *store, - const TypedRegion *region); - - void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, store, region); } -}; - -class BasicValueFactory { - typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> > - APSIntSetTy; - - ASTContext& Ctx; - llvm::BumpPtrAllocator& BPAlloc; - - APSIntSetTy APSIntSet; - void* PersistentSVals; - void* PersistentSValPairs; - - llvm::ImmutableList<SVal>::Factory SValListFactory; - llvm::FoldingSet<CompoundValData> CompoundValDataSet; - llvm::FoldingSet<LazyCompoundValData> LazyCompoundValDataSet; - -public: - BasicValueFactory(ASTContext& ctx, llvm::BumpPtrAllocator& Alloc) - : Ctx(ctx), BPAlloc(Alloc), PersistentSVals(0), PersistentSValPairs(0), - SValListFactory(Alloc) {} - - ~BasicValueFactory(); - - ASTContext& getContext() const { return Ctx; } - - const llvm::APSInt& getValue(const llvm::APSInt& X); - const llvm::APSInt& getValue(const llvm::APInt& X, bool isUnsigned); - const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned); - const llvm::APSInt& getValue(uint64_t X, QualType T); - - /// Convert - Create a new persistent APSInt with the same value as 'From' - /// but with the bitwidth and signedness of 'To'. - const llvm::APSInt &Convert(const llvm::APSInt& To, - const llvm::APSInt& From) { - - if (To.isUnsigned() == From.isUnsigned() && - To.getBitWidth() == From.getBitWidth()) - return From; - - return getValue(From.getSExtValue(), To.getBitWidth(), To.isUnsigned()); - } - - const llvm::APSInt &Convert(QualType T, const llvm::APSInt &From) { - assert(T->isIntegerType() || Loc::IsLocType(T)); - unsigned bitwidth = Ctx.getTypeSize(T); - bool isUnsigned = T->isUnsignedIntegerType() || Loc::IsLocType(T); - - if (isUnsigned == From.isUnsigned() && bitwidth == From.getBitWidth()) - return From; - - return getValue(From.getSExtValue(), bitwidth, isUnsigned); - } - - const llvm::APSInt& getIntValue(uint64_t X, bool isUnsigned) { - QualType T = isUnsigned ? Ctx.UnsignedIntTy : Ctx.IntTy; - return getValue(X, T); - } - - inline const llvm::APSInt& getMaxValue(const llvm::APSInt &v) { - return getValue(llvm::APSInt::getMaxValue(v.getBitWidth(), v.isUnsigned())); - } - - inline const llvm::APSInt& getMinValue(const llvm::APSInt &v) { - return getValue(llvm::APSInt::getMinValue(v.getBitWidth(), v.isUnsigned())); - } - - inline const llvm::APSInt& getMaxValue(QualType T) { - assert(T->isIntegerType() || Loc::IsLocType(T)); - bool isUnsigned = T->isUnsignedIntegerType() || Loc::IsLocType(T); - return getValue(llvm::APSInt::getMaxValue(Ctx.getTypeSize(T), isUnsigned)); - } - - inline const llvm::APSInt& getMinValue(QualType T) { - assert(T->isIntegerType() || Loc::IsLocType(T)); - bool isUnsigned = T->isUnsignedIntegerType() || Loc::IsLocType(T); - return getValue(llvm::APSInt::getMinValue(Ctx.getTypeSize(T), isUnsigned)); - } - - inline const llvm::APSInt& Add1(const llvm::APSInt& V) { - llvm::APSInt X = V; - ++X; - return getValue(X); - } - - inline const llvm::APSInt& Sub1(const llvm::APSInt& V) { - llvm::APSInt X = V; - --X; - return getValue(X); - } - - inline const llvm::APSInt& getZeroWithPtrWidth(bool isUnsigned = true) { - return getValue(0, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned); - } - - inline const llvm::APSInt &getIntWithPtrWidth(uint64_t X, bool isUnsigned) { - return getValue(X, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned); - } - - inline const llvm::APSInt& getTruthValue(bool b, QualType T) { - return getValue(b ? 1 : 0, Ctx.getTypeSize(T), false); - } - - inline const llvm::APSInt& getTruthValue(bool b) { - return getTruthValue(b, Ctx.IntTy); - } - - const CompoundValData *getCompoundValData(QualType T, - llvm::ImmutableList<SVal> Vals); - - const LazyCompoundValData *getLazyCompoundValData(const void *store, - const TypedRegion *region); - - llvm::ImmutableList<SVal> getEmptySValList() { - return SValListFactory.GetEmptyList(); - } - - llvm::ImmutableList<SVal> consVals(SVal X, llvm::ImmutableList<SVal> L) { - return SValListFactory.Add(X, L); - } - - const llvm::APSInt* EvaluateAPSInt(BinaryOperator::Opcode Op, - const llvm::APSInt& V1, - const llvm::APSInt& V2); - - const std::pair<SVal, uintptr_t>& - getPersistentSValWithData(const SVal& V, uintptr_t Data); - - const std::pair<SVal, SVal>& - getPersistentSValPair(const SVal& V1, const SVal& V2); - - const SVal* getPersistentSVal(SVal X); -}; - -} // end clang namespace - -#endif diff --git a/include/clang/Checker/PathSensitive/Checker.h b/include/clang/Checker/PathSensitive/Checker.h deleted file mode 100644 index 136a29d..0000000 --- a/include/clang/Checker/PathSensitive/Checker.h +++ /dev/null @@ -1,308 +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_ANALYSIS_CHECKER -#define LLVM_CLANG_ANALYSIS_CHECKER - -#include "clang/Analysis/Support/SaveAndRestore.h" -#include "clang/Checker/PathSensitive/GRExprEngine.h" - -//===----------------------------------------------------------------------===// -// Checker interface. -//===----------------------------------------------------------------------===// - -namespace clang { - -class CheckerContext { - ExplodedNodeSet &Dst; - GRStmtNodeBuilder &B; - GRExprEngine &Eng; - ExplodedNode *Pred; - SaveAndRestore<bool> OldSink; - SaveAndRestore<const void*> OldTag; - SaveAndRestore<ProgramPoint::Kind> OldPointKind; - SaveOr OldHasGen; - const GRState *ST; - const Stmt *statement; - const unsigned size; -public: - bool *respondsToCallback; -public: - CheckerContext(ExplodedNodeSet &dst, GRStmtNodeBuilder &builder, - GRExprEngine &eng, ExplodedNode *pred, - const void *tag, ProgramPoint::Kind K, - bool *respondsToCB = 0, - const Stmt *stmt = 0, const GRState *st = 0) - : Dst(dst), B(builder), Eng(eng), Pred(pred), - OldSink(B.BuildSinks), - OldTag(B.Tag, tag), - OldPointKind(B.PointKind, K), - OldHasGen(B.HasGeneratedNode), - ST(st), statement(stmt), size(Dst.size()), - respondsToCallback(respondsToCB) {} - - ~CheckerContext(); - - GRExprEngine &getEngine() { - return Eng; - } - - AnalysisManager &getAnalysisManager() { - return Eng.getAnalysisManager(); - } - - ConstraintManager &getConstraintManager() { - return Eng.getConstraintManager(); - } - - StoreManager &getStoreManager() { - return Eng.getStoreManager(); - } - - ExplodedNodeSet &getNodeSet() { return Dst; } - GRStmtNodeBuilder &getNodeBuilder() { return B; } - ExplodedNode *&getPredecessor() { return Pred; } - const GRState *getState() { return ST ? ST : B.GetState(Pred); } - - ASTContext &getASTContext() { - return Eng.getContext(); - } - - BugReporter &getBugReporter() { - return Eng.getBugReporter(); - } - - SourceManager &getSourceManager() { - return getBugReporter().getSourceManager(); - } - - ValueManager &getValueManager() { - return Eng.getValueManager(); - } - - SValuator &getSValuator() { - return Eng.getSValuator(); - } - - ExplodedNode *GenerateNode(bool autoTransition = true) { - assert(statement && "Only transitions with statements currently supported"); - ExplodedNode *N = GenerateNodeImpl(statement, getState(), false); - if (N && autoTransition) - Dst.Add(N); - return N; - } - - ExplodedNode *GenerateNode(const Stmt *stmt, const GRState *state, - bool autoTransition = true) { - assert(state); - ExplodedNode *N = GenerateNodeImpl(stmt, state, false); - if (N && autoTransition) - addTransition(N); - return N; - } - - ExplodedNode *GenerateNode(const GRState *state, ExplodedNode *pred, - bool autoTransition = true) { - assert(statement && "Only transitions with statements currently supported"); - ExplodedNode *N = GenerateNodeImpl(statement, state, pred, false); - if (N && autoTransition) - addTransition(N); - return N; - } - - ExplodedNode *GenerateNode(const GRState *state, bool autoTransition = true) { - assert(statement && "Only transitions with statements currently supported"); - ExplodedNode *N = GenerateNodeImpl(statement, state, false); - if (N && autoTransition) - addTransition(N); - return N; - } - - ExplodedNode *GenerateSink(const Stmt *stmt, const GRState *state = 0) { - return GenerateNodeImpl(stmt, state ? state : getState(), true); - } - - ExplodedNode *GenerateSink(const GRState *state = 0) { - assert(statement && "Only transitions with statements currently supported"); - return GenerateNodeImpl(statement, state ? state : getState(), true); - } - - void addTransition(ExplodedNode *node) { - Dst.Add(node); - } - - void addTransition(const GRState *state) { - assert(state); - // If the 'state' is not new, we need to check if the cached state 'ST' - // is new. - if (state != getState() || (ST && ST != B.GetState(Pred))) - // state is new or equals to ST. - GenerateNode(state, true); - else - Dst.Add(Pred); - } - - // Generate a node with a new program point different from the one that will - // be created by the GRStmtNodeBuilder. - void addTransition(const GRState *state, ProgramPoint Loc) { - ExplodedNode *N = B.generateNode(Loc, state, Pred); - if (N) - addTransition(N); - } - - void EmitReport(BugReport *R) { - Eng.getBugReporter().EmitReport(R); - } - - AnalysisContext *getCurrentAnalysisContext() const { - return Pred->getLocationContext()->getAnalysisContext(); - } - -private: - ExplodedNode *GenerateNodeImpl(const Stmt* stmt, const GRState *state, - bool markAsSink) { - ExplodedNode *node = B.generateNode(stmt, state, Pred); - if (markAsSink && node) - node->markAsSink(); - return node; - } - - ExplodedNode *GenerateNodeImpl(const Stmt* stmt, const GRState *state, - ExplodedNode *pred, bool markAsSink) { - ExplodedNode *node = B.generateNode(stmt, state, pred); - if (markAsSink && node) - node->markAsSink(); - return node; - } -}; - -class Checker { -private: - friend class GRExprEngine; - - // FIXME: Remove the 'tag' option. - void GR_Visit(ExplodedNodeSet &Dst, - GRStmtNodeBuilder &Builder, - GRExprEngine &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); - } - - bool GR_EvalNilReceiver(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder, - GRExprEngine &Eng, const ObjCMessageExpr *ME, - ExplodedNode *Pred, const GRState *state, void *tag) { - CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind, - 0, ME, state); - return EvalNilReceiver(C, ME); - } - - bool GR_EvalCallExpr(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder, - GRExprEngine &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, - GRStmtNodeBuilder &Builder, GRExprEngine &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, - GRStmtNodeBuilder &Builder, - GRExprEngine &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); - } - - void GR_EvalDeadSymbols(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder, - GRExprEngine &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 VisitLocation(CheckerContext &C, const Stmt *S, SVal location) {} - virtual void PreVisitBind(CheckerContext &C, const Stmt *StoreE, - SVal location, SVal val) {} - virtual void EvalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper) {} - virtual void EvalEndPath(GREndPathNodeBuilder &B, void *tag, - GRExprEngine &Eng) {} - - virtual void MarkLiveSymbols(const GRState *state, SymbolReaper &SymReaper) {} - - virtual void VisitBranchCondition(GRBranchNodeBuilder &Builder, - GRExprEngine &Eng, - const Stmt *Condition, void *tag) {} - - virtual bool EvalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME) { - 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, - GRExprEngine &Eng) {} -}; -} // end clang namespace - -#endif - diff --git a/include/clang/Checker/PathSensitive/CheckerHelpers.h b/include/clang/Checker/PathSensitive/CheckerHelpers.h deleted file mode 100644 index ea3c842..0000000 --- a/include/clang/Checker/PathSensitive/CheckerHelpers.h +++ /dev/null @@ -1,40 +0,0 @@ -//== CheckerHelpers.h - Helper functions 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_CHECKER_PATHSENSITIVE_CHECKERHELPERS -#define LLVM_CLANG_CHECKER_PATHSENSITIVE_CHECKERHELPERS - -#include "clang/AST/Stmt.h" - -namespace clang { - -bool containsMacro(const Stmt *S); -bool containsEnum(const Stmt *S); -bool containsStaticLocal(const Stmt *S); -bool containsBuiltinOffsetOf(const Stmt *S); -template <class T> bool containsStmt(const Stmt *S) { - if (isa<T>(S)) - return true; - - for (Stmt::const_child_iterator I = S->child_begin(); I != S->child_end(); - ++I) - if (const Stmt *child = *I) - if (containsStmt<T>(child)) - return true; - - return false; -} - -} - -#endif diff --git a/include/clang/Checker/PathSensitive/CheckerVisitor.def b/include/clang/Checker/PathSensitive/CheckerVisitor.def deleted file mode 100644 index 2edc4a3..0000000 --- a/include/clang/Checker/PathSensitive/CheckerVisitor.def +++ /dev/null @@ -1,37 +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, Stmt) -PREVISIT(CXXOperatorCallExpr, CallExpr) -PREVISIT(DeclStmt, Stmt) -PREVISIT(ObjCMessageExpr, Stmt) -PREVISIT(ReturnStmt, Stmt) - -POSTVISIT(BlockExpr, Stmt) -POSTVISIT(BinaryOperator, Stmt) -POSTVISIT(CallExpr, Stmt) -POSTVISIT(CXXOperatorCallExpr, CallExpr) -POSTVISIT(ObjCMessageExpr, Stmt) - -#undef PREVISIT -#undef POSTVISIT diff --git a/include/clang/Checker/PathSensitive/CheckerVisitor.h b/include/clang/Checker/PathSensitive/CheckerVisitor.h deleted file mode 100644 index e2ba89b..0000000 --- a/include/clang/Checker/PathSensitive/CheckerVisitor.h +++ /dev/null @@ -1,107 +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_ANALYSIS_CHECKERVISITOR -#define LLVM_CLANG_ANALYSIS_CHECKERVISITOR -#include "clang/Checker/PathSensitive/Checker.h" - -namespace clang { - -//===----------------------------------------------------------------------===// -// 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; - - case Stmt::ImplicitCastExprClass: - case Stmt::CStyleCastExprClass: - static_cast<ImplClass*>(this)->PreVisitCastExpr(C, - static_cast<const CastExpr*>(S)); - break; - - case Stmt::CompoundAssignOperatorClass: - static_cast<ImplClass*>(this)->PreVisitBinaryOperator(C, - static_cast<const BinaryOperator*>(S)); - break; - -#define PREVISIT(NAME, FALLBACK) \ -case Stmt::NAME ## Class:\ -static_cast<ImplClass*>(this)->PreVisit ## NAME(C,static_cast<const NAME*>(S));\ -break; -#include "clang/Checker/PathSensitive/CheckerVisitor.def" - } - } - - void PostVisit(CheckerContext &C, const Stmt *S) { - switch (S->getStmtClass()) { - default: - assert(false && "Unsupport statement."); - return; - case Stmt::CompoundAssignOperatorClass: - static_cast<ImplClass*>(this)->PostVisitBinaryOperator(C, - static_cast<const BinaryOperator*>(S)); - break; - -#define POSTVISIT(NAME, FALLBACK) \ -case Stmt::NAME ## Class:\ -static_cast<ImplClass*>(this)->\ -PostVisit ## NAME(C,static_cast<const NAME*>(S));\ -break; -#include "clang/Checker/PathSensitive/CheckerVisitor.def" - } - } - - 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/Checker/PathSensitive/CheckerVisitor.def" -}; - -} // end clang namespace - -#endif diff --git a/include/clang/Checker/PathSensitive/ConstraintManager.h b/include/clang/Checker/PathSensitive/ConstraintManager.h deleted file mode 100644 index 97535f5..0000000 --- a/include/clang/Checker/PathSensitive/ConstraintManager.h +++ /dev/null @@ -1,72 +0,0 @@ -//== ConstraintManager.h - Constraints on symbolic values.-------*- 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 interface to manage constraints on symbolic values. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_CONSTRAINT_MANAGER_H -#define LLVM_CLANG_ANALYSIS_CONSTRAINT_MANAGER_H - -// FIXME: Typedef LiveSymbolsTy/DeadSymbolsTy at a more appropriate place. -#include "clang/Checker/PathSensitive/Store.h" - -namespace llvm { -class APSInt; -} - -namespace clang { - -class GRState; -class GRStateManager; -class GRSubEngine; -class SVal; - -class ConstraintManager { -public: - virtual ~ConstraintManager(); - virtual const GRState *Assume(const GRState *state, DefinedSVal Cond, - bool Assumption) = 0; - - std::pair<const GRState*, const GRState*> AssumeDual(const GRState *state, - DefinedSVal Cond) { - return std::make_pair(Assume(state, Cond, true), - Assume(state, Cond, false)); - } - - virtual const llvm::APSInt* getSymVal(const GRState *state, - SymbolRef sym) const = 0; - - virtual bool isEqual(const GRState *state, SymbolRef sym, - const llvm::APSInt& V) const = 0; - - virtual const GRState *RemoveDeadBindings(const GRState *state, - SymbolReaper& SymReaper) = 0; - - virtual void print(const GRState *state, llvm::raw_ostream& Out, - const char* nl, const char *sep) = 0; - - virtual void EndPath(const GRState *state) {} - - /// canReasonAbout - Not all ConstraintManagers can accurately reason about - /// all SVal values. This method returns true if the ConstraintManager can - /// reasonably handle a given SVal value. This is typically queried by - /// GRExprEngine to determine if the value should be replaced with a - /// conjured symbolic value in order to recover some precision. - virtual bool canReasonAbout(SVal X) const = 0; -}; - -ConstraintManager* CreateBasicConstraintManager(GRStateManager& statemgr, - GRSubEngine &subengine); -ConstraintManager* CreateRangeConstraintManager(GRStateManager& statemgr, - GRSubEngine &subengine); - -} // end clang namespace - -#endif diff --git a/include/clang/Checker/PathSensitive/Environment.h b/include/clang/Checker/PathSensitive/Environment.h deleted file mode 100644 index 611f507..0000000 --- a/include/clang/Checker/PathSensitive/Environment.h +++ /dev/null @@ -1,102 +0,0 @@ -//== Environment.h - Map from Stmt* to Locations/Values ---------*- 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 Environment and EnvironmentManager classes. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_ENVIRONMENT_H -#define LLVM_CLANG_ANALYSIS_ENVIRONMENT_H - -// For using typedefs in StoreManager. Should find a better place for these -// typedefs. -#include "clang/Checker/PathSensitive/Store.h" - -#include "clang/Checker/PathSensitive/SVals.h" -#include "llvm/ADT/ImmutableMap.h" - -namespace clang { - -class EnvironmentManager; -class ValueManager; -class LiveVariables; - - -class Environment { -private: - friend class EnvironmentManager; - - // Type definitions. - typedef llvm::ImmutableMap<const Stmt*,SVal> BindingsTy; - - // Data. - BindingsTy ExprBindings; - - Environment(BindingsTy eb) - : ExprBindings(eb) {} - -public: - typedef BindingsTy::iterator iterator; - iterator begin() const { return ExprBindings.begin(); } - iterator end() const { return ExprBindings.end(); } - - SVal LookupExpr(const Stmt* E) const { - const SVal* X = ExprBindings.lookup(E); - return X ? *X : UnknownVal(); - } - - SVal GetSVal(const Stmt* Ex, ValueManager& ValMgr) const; - - /// Profile - Profile the contents of an Environment object for use - /// in a FoldingSet. - static void Profile(llvm::FoldingSetNodeID& ID, const Environment* E) { - E->ExprBindings.Profile(ID); - } - - /// Profile - Used to profile the contents of this object for inclusion - /// in a FoldingSet. - void Profile(llvm::FoldingSetNodeID& ID) const { - Profile(ID, this); - } - - bool operator==(const Environment& RHS) const { - return ExprBindings == RHS.ExprBindings; - } -}; - -class EnvironmentManager { -private: - typedef Environment::BindingsTy::Factory FactoryTy; - FactoryTy F; - -public: - EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {} - ~EnvironmentManager() {} - - Environment getInitialEnvironment() { - return Environment(F.GetEmptyMap()); - } - - /// Bind the value 'V' to the statement 'S'. - Environment bindExpr(Environment Env, const Stmt *S, SVal V, - bool Invalidate); - - /// Bind the location 'location' and value 'V' to the statement 'S'. This - /// is used when simulating loads/stores. - Environment bindExprAndLocation(Environment Env, const Stmt *S, SVal location, - SVal V); - - Environment RemoveDeadBindings(Environment Env, - SymbolReaper &SymReaper, const GRState *ST, - llvm::SmallVectorImpl<const MemRegion*>& RegionRoots); -}; - -} // end clang namespace - -#endif diff --git a/include/clang/Checker/PathSensitive/ExplodedGraph.h b/include/clang/Checker/PathSensitive/ExplodedGraph.h deleted file mode 100644 index c875a23..0000000 --- a/include/clang/Checker/PathSensitive/ExplodedGraph.h +++ /dev/null @@ -1,430 +0,0 @@ -//=-- ExplodedGraph.h - Local, Path-Sens. "Exploded Graph" -*- C++ -*-------==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the template classes ExplodedNode and ExplodedGraph, -// which represent a path-sensitive, intra-procedural "exploded graph." -// See "Precise interprocedural dataflow analysis via graph reachability" -// by Reps, Horwitz, and Sagiv -// (http://portal.acm.org/citation.cfm?id=199462) for the definition of an -// exploded graph. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_EXPLODEDGRAPH -#define LLVM_CLANG_ANALYSIS_EXPLODEDGRAPH - -#include "clang/Analysis/ProgramPoint.h" -#include "clang/Analysis/AnalysisContext.h" -#include "clang/AST/Decl.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/Support/Allocator.h" -#include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/GraphTraits.h" -#include "llvm/ADT/DepthFirstIterator.h" -#include "llvm/Support/Casting.h" -#include "clang/Analysis/Support/BumpVector.h" - -namespace clang { - -class GRState; -class CFG; -class ExplodedGraph; - -//===----------------------------------------------------------------------===// -// ExplodedGraph "implementation" classes. These classes are not typed to -// contain a specific kind of state. Typed-specialized versions are defined -// on top of these classes. -//===----------------------------------------------------------------------===// - -class ExplodedNode : public llvm::FoldingSetNode { - friend class ExplodedGraph; - friend class GRCoreEngine; - friend class GRStmtNodeBuilder; - friend class GRBranchNodeBuilder; - friend class GRIndirectGotoNodeBuilder; - friend class GRSwitchNodeBuilder; - friend class GREndPathNodeBuilder; - - class NodeGroup { - enum { Size1 = 0x0, SizeOther = 0x1, AuxFlag = 0x2, Mask = 0x3 }; - uintptr_t P; - - unsigned getKind() const { - return P & 0x1; - } - - void* getPtr() const { - assert (!getFlag()); - return reinterpret_cast<void*>(P & ~Mask); - } - - ExplodedNode *getNode() const { - return reinterpret_cast<ExplodedNode*>(getPtr()); - } - - public: - NodeGroup() : P(0) {} - - ExplodedNode **begin() const; - - ExplodedNode **end() const; - - unsigned size() const; - - bool empty() const { return (P & ~Mask) == 0; } - - void addNode(ExplodedNode* N, ExplodedGraph &G); - - void setFlag() { - assert(P == 0); - P = AuxFlag; - } - - bool getFlag() const { - return P & AuxFlag ? true : false; - } - }; - - /// Location - The program location (within a function body) associated - /// with this node. - const ProgramPoint Location; - - /// State - The state associated with this node. - const GRState* State; - - /// Preds - The predecessors of this node. - NodeGroup Preds; - - /// Succs - The successors of this node. - NodeGroup Succs; - -public: - - explicit ExplodedNode(const ProgramPoint& loc, const GRState* state) - : Location(loc), State(state) {} - - /// getLocation - Returns the edge associated with the given node. - ProgramPoint getLocation() const { return Location; } - - const LocationContext *getLocationContext() const { - return getLocation().getLocationContext(); - } - - const Decl &getCodeDecl() const { return *getLocationContext()->getDecl(); } - - CFG &getCFG() const { return *getLocationContext()->getCFG(); } - - ParentMap &getParentMap() const {return getLocationContext()->getParentMap();} - - LiveVariables &getLiveVariables() const { - return *getLocationContext()->getLiveVariables(); - } - - const GRState* getState() const { return State; } - - template <typename T> - const T* getLocationAs() const { return llvm::dyn_cast<T>(&Location); } - - static void Profile(llvm::FoldingSetNodeID &ID, - const ProgramPoint& Loc, const GRState* state) { - ID.Add(Loc); - ID.AddPointer(state); - } - - void Profile(llvm::FoldingSetNodeID& ID) const { - Profile(ID, getLocation(), getState()); - } - - /// addPredeccessor - Adds a predecessor to the current node, and - /// in tandem add this node as a successor of the other node. - void addPredecessor(ExplodedNode* V, ExplodedGraph &G); - - unsigned succ_size() const { return Succs.size(); } - unsigned pred_size() const { return Preds.size(); } - bool succ_empty() const { return Succs.empty(); } - bool pred_empty() const { return Preds.empty(); } - - bool isSink() const { return Succs.getFlag(); } - void markAsSink() { Succs.setFlag(); } - - ExplodedNode* getFirstPred() { - return pred_empty() ? NULL : *(pred_begin()); - } - - const ExplodedNode* getFirstPred() const { - return const_cast<ExplodedNode*>(this)->getFirstPred(); - } - - // Iterators over successor and predecessor vertices. - typedef ExplodedNode** succ_iterator; - typedef const ExplodedNode* const * const_succ_iterator; - typedef ExplodedNode** pred_iterator; - typedef const ExplodedNode* const * const_pred_iterator; - - pred_iterator pred_begin() { return Preds.begin(); } - pred_iterator pred_end() { return Preds.end(); } - - const_pred_iterator pred_begin() const { - return const_cast<ExplodedNode*>(this)->pred_begin(); - } - const_pred_iterator pred_end() const { - return const_cast<ExplodedNode*>(this)->pred_end(); - } - - succ_iterator succ_begin() { return Succs.begin(); } - succ_iterator succ_end() { return Succs.end(); } - - const_succ_iterator succ_begin() const { - return const_cast<ExplodedNode*>(this)->succ_begin(); - } - const_succ_iterator succ_end() const { - return const_cast<ExplodedNode*>(this)->succ_end(); - } - - // For debugging. - -public: - - class Auditor { - public: - virtual ~Auditor(); - virtual void AddEdge(ExplodedNode* Src, ExplodedNode* Dst) = 0; - }; - - static void SetAuditor(Auditor* A); -}; - -// FIXME: Is this class necessary? -class InterExplodedGraphMap { - llvm::DenseMap<const ExplodedNode*, ExplodedNode*> M; - friend class ExplodedGraph; - -public: - ExplodedNode* getMappedNode(const ExplodedNode* N) const; - - InterExplodedGraphMap() {} - virtual ~InterExplodedGraphMap() {} -}; - -class ExplodedGraph { -protected: - friend class GRCoreEngine; - - // Type definitions. - typedef llvm::SmallVector<ExplodedNode*,2> RootsTy; - typedef llvm::SmallVector<ExplodedNode*,10> EndNodesTy; - - /// Roots - The roots of the simulation graph. Usually there will be only - /// one, but clients are free to establish multiple subgraphs within a single - /// SimulGraph. Moreover, these subgraphs can often merge when paths from - /// different roots reach the same state at the same program location. - RootsTy Roots; - - /// EndNodes - The nodes in the simulation graph which have been - /// specially marked as the endpoint of an abstract simulation path. - EndNodesTy EndNodes; - - /// Nodes - The nodes in the graph. - llvm::FoldingSet<ExplodedNode> Nodes; - - /// BVC - Allocator and context for allocating nodes and their predecessor - /// and successor groups. - BumpVectorContext BVC; - - /// NumNodes - The number of nodes in the graph. - unsigned NumNodes; - -public: - /// getNode - Retrieve the node associated with a (Location,State) pair, - /// where the 'Location' is a ProgramPoint in the CFG. If no node for - /// this pair exists, it is created. IsNew is set to true if - /// the node was freshly created. - - ExplodedNode* getNode(const ProgramPoint& L, const GRState *State, - bool* IsNew = 0); - - ExplodedGraph* MakeEmptyGraph() const { - return new ExplodedGraph(); - } - - /// addRoot - Add an untyped node to the set of roots. - ExplodedNode* addRoot(ExplodedNode* V) { - Roots.push_back(V); - return V; - } - - /// addEndOfPath - Add an untyped node to the set of EOP nodes. - ExplodedNode* addEndOfPath(ExplodedNode* V) { - EndNodes.push_back(V); - return V; - } - - ExplodedGraph() : NumNodes(0) {} - - ~ExplodedGraph() {} - - unsigned num_roots() const { return Roots.size(); } - unsigned num_eops() const { return EndNodes.size(); } - - bool empty() const { return NumNodes == 0; } - unsigned size() const { return NumNodes; } - - // Iterators. - typedef ExplodedNode NodeTy; - typedef llvm::FoldingSet<ExplodedNode> AllNodesTy; - typedef NodeTy** roots_iterator; - typedef NodeTy* const * const_roots_iterator; - typedef NodeTy** eop_iterator; - typedef NodeTy* const * const_eop_iterator; - typedef AllNodesTy::iterator node_iterator; - typedef AllNodesTy::const_iterator const_node_iterator; - - node_iterator nodes_begin() { return Nodes.begin(); } - - node_iterator nodes_end() { return Nodes.end(); } - - const_node_iterator nodes_begin() const { return Nodes.begin(); } - - const_node_iterator nodes_end() const { return Nodes.end(); } - - roots_iterator roots_begin() { return Roots.begin(); } - - roots_iterator roots_end() { return Roots.end(); } - - const_roots_iterator roots_begin() const { return Roots.begin(); } - - const_roots_iterator roots_end() const { return Roots.end(); } - - eop_iterator eop_begin() { return EndNodes.begin(); } - - eop_iterator eop_end() { return EndNodes.end(); } - - const_eop_iterator eop_begin() const { return EndNodes.begin(); } - - const_eop_iterator eop_end() const { return EndNodes.end(); } - - llvm::BumpPtrAllocator & getAllocator() { return BVC.getAllocator(); } - BumpVectorContext &getNodeAllocator() { return BVC; } - - typedef llvm::DenseMap<const ExplodedNode*, ExplodedNode*> NodeMap; - - std::pair<ExplodedGraph*, InterExplodedGraphMap*> - Trim(const NodeTy* const* NBeg, const NodeTy* const* NEnd, - llvm::DenseMap<const void*, const void*> *InverseMap = 0) const; - - ExplodedGraph* TrimInternal(const ExplodedNode* const * NBeg, - const ExplodedNode* const * NEnd, - InterExplodedGraphMap *M, - llvm::DenseMap<const void*, const void*> *InverseMap) const; -}; - -class ExplodedNodeSet { - typedef llvm::SmallPtrSet<ExplodedNode*,5> ImplTy; - ImplTy Impl; - -public: - ExplodedNodeSet(ExplodedNode* N) { - assert (N && !static_cast<ExplodedNode*>(N)->isSink()); - Impl.insert(N); - } - - ExplodedNodeSet() {} - - inline void Add(ExplodedNode* N) { - if (N && !static_cast<ExplodedNode*>(N)->isSink()) Impl.insert(N); - } - - ExplodedNodeSet& operator=(const ExplodedNodeSet &X) { - Impl = X.Impl; - return *this; - } - - typedef ImplTy::iterator iterator; - typedef ImplTy::const_iterator const_iterator; - - unsigned size() const { return Impl.size(); } - bool empty() const { return Impl.empty(); } - - void clear() { Impl.clear(); } - void insert(const ExplodedNodeSet &S) { - if (empty()) - Impl = S.Impl; - else - Impl.insert(S.begin(), S.end()); - } - - inline iterator begin() { return Impl.begin(); } - inline iterator end() { return Impl.end(); } - - inline const_iterator begin() const { return Impl.begin(); } - inline const_iterator end() const { return Impl.end(); } -}; - -} // end clang namespace - -// GraphTraits - -namespace llvm { - template<> struct GraphTraits<clang::ExplodedNode*> { - typedef clang::ExplodedNode NodeType; - typedef NodeType::succ_iterator ChildIteratorType; - typedef llvm::df_iterator<NodeType*> nodes_iterator; - - static inline NodeType* getEntryNode(NodeType* N) { - return N; - } - - static inline ChildIteratorType child_begin(NodeType* N) { - return N->succ_begin(); - } - - static inline ChildIteratorType child_end(NodeType* N) { - return N->succ_end(); - } - - static inline nodes_iterator nodes_begin(NodeType* N) { - return df_begin(N); - } - - static inline nodes_iterator nodes_end(NodeType* N) { - return df_end(N); - } - }; - - template<> struct GraphTraits<const clang::ExplodedNode*> { - typedef const clang::ExplodedNode NodeType; - typedef NodeType::const_succ_iterator ChildIteratorType; - typedef llvm::df_iterator<NodeType*> nodes_iterator; - - static inline NodeType* getEntryNode(NodeType* N) { - return N; - } - - static inline ChildIteratorType child_begin(NodeType* N) { - return N->succ_begin(); - } - - static inline ChildIteratorType child_end(NodeType* N) { - return N->succ_end(); - } - - static inline nodes_iterator nodes_begin(NodeType* N) { - return df_begin(N); - } - - static inline nodes_iterator nodes_end(NodeType* N) { - return df_end(N); - } - }; - -} // end llvm namespace - -#endif diff --git a/include/clang/Checker/PathSensitive/GRAuditor.h b/include/clang/Checker/PathSensitive/GRAuditor.h deleted file mode 100644 index 015c82e..0000000 --- a/include/clang/Checker/PathSensitive/GRAuditor.h +++ /dev/null @@ -1,35 +0,0 @@ -//==- GRAuditor.h - Observers of the creation of ExplodedNodes------*- 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 GRAuditor and its primary subclasses, an interface -// to audit the creation of ExplodedNodes. This interface can be used -// to implement simple checkers that do not mutate analysis state but -// instead operate by perfoming simple logical checks at key monitoring -// locations (e.g., function calls). -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_GRAUDITOR -#define LLVM_CLANG_ANALYSIS_GRAUDITOR - -namespace clang { - -class ExplodedNode; -class GRStateManager; - -class GRAuditor { -public: - virtual ~GRAuditor() {} - virtual bool Audit(ExplodedNode* N, GRStateManager& M) = 0; -}; - - -} // end clang namespace - -#endif diff --git a/include/clang/Checker/PathSensitive/GRBlockCounter.h b/include/clang/Checker/PathSensitive/GRBlockCounter.h deleted file mode 100644 index b7d0e8a..0000000 --- a/include/clang/Checker/PathSensitive/GRBlockCounter.h +++ /dev/null @@ -1,55 +0,0 @@ -//==- GRBlockCounter.h - ADT for counting block visits -------------*- 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 GRBlockCounter, an abstract data type used to count -// the number of times a given block has been visited along a path -// analyzed by GRCoreEngine. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_GRBLOCKCOUNTER -#define LLVM_CLANG_ANALYSIS_GRBLOCKCOUNTER - -namespace llvm { - class BumpPtrAllocator; -} - -namespace clang { - -class StackFrameContext; - -class GRBlockCounter { - void* Data; - - GRBlockCounter(void* D) : Data(D) {} - -public: - GRBlockCounter() : Data(0) {} - - unsigned getNumVisited(const StackFrameContext *CallSite, - unsigned BlockID) const; - - class Factory { - void* F; - public: - Factory(llvm::BumpPtrAllocator& Alloc); - ~Factory(); - - GRBlockCounter GetEmptyCounter(); - GRBlockCounter IncrementCount(GRBlockCounter BC, - const StackFrameContext *CallSite, - unsigned BlockID); - }; - - friend class Factory; -}; - -} // end clang namespace - -#endif diff --git a/include/clang/Checker/PathSensitive/GRCoreEngine.h b/include/clang/Checker/PathSensitive/GRCoreEngine.h deleted file mode 100644 index 216ecac..0000000 --- a/include/clang/Checker/PathSensitive/GRCoreEngine.h +++ /dev/null @@ -1,531 +0,0 @@ -//==- GRCoreEngine.h - Path-Sensitive Dataflow Engine --------------*- 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 a generic engine for intraprocedural, path-sensitive, -// dataflow analysis via graph reachability. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_GRENGINE -#define LLVM_CLANG_ANALYSIS_GRENGINE - -#include "clang/AST/Expr.h" -#include "clang/Checker/PathSensitive/ExplodedGraph.h" -#include "clang/Checker/PathSensitive/GRWorkList.h" -#include "clang/Checker/PathSensitive/GRBlockCounter.h" -#include "clang/Checker/PathSensitive/GRAuditor.h" -#include "clang/Checker/PathSensitive/GRSubEngine.h" -#include "llvm/ADT/OwningPtr.h" - -namespace clang { - -//===----------------------------------------------------------------------===// -/// GRCoreEngine - Implements the core logic of the graph-reachability -/// analysis. It traverses the CFG and generates the ExplodedGraph. -/// Program "states" are treated as opaque void pointers. -/// The template class GRCoreEngine (which subclasses GRCoreEngine) -/// provides the matching component to the engine that knows the actual types -/// for states. Note that this engine only dispatches to transfer functions -/// at the statement and block-level. The analyses themselves must implement -/// any transfer function logic and the sub-expression level (if any). -class GRCoreEngine { - friend class GRStmtNodeBuilder; - friend class GRBranchNodeBuilder; - friend class GRIndirectGotoNodeBuilder; - friend class GRSwitchNodeBuilder; - friend class GREndPathNodeBuilder; - friend class GRCallEnterNodeBuilder; - friend class GRCallExitNodeBuilder; - -public: - typedef std::vector<std::pair<BlockEdge, const ExplodedNode*> > - BlocksAborted; -private: - - GRSubEngine& SubEngine; - - /// G - The simulation graph. Each node is a (location,state) pair. - llvm::OwningPtr<ExplodedGraph> G; - - /// WList - A set of queued nodes that need to be processed by the - /// worklist algorithm. It is up to the implementation of WList to decide - /// the order that nodes are processed. - GRWorkList* WList; - - /// BCounterFactory - A factory object for created GRBlockCounter objects. - /// These are used to record for key nodes in the ExplodedGraph the - /// number of times different CFGBlocks have been visited along a path. - GRBlockCounter::Factory BCounterFactory; - - /// The locations where we stopped doing work because we visited a location - /// too many times. - BlocksAborted blocksAborted; - - void GenerateNode(const ProgramPoint& Loc, const GRState* State, - ExplodedNode* Pred); - - void HandleBlockEdge(const BlockEdge& E, ExplodedNode* Pred); - void HandleBlockEntrance(const BlockEntrance& E, ExplodedNode* Pred); - void HandleBlockExit(const CFGBlock* B, ExplodedNode* Pred); - void HandlePostStmt(const PostStmt& S, const CFGBlock* B, - unsigned StmtIdx, ExplodedNode *Pred); - - void HandleBranch(const Stmt* Cond, const Stmt* Term, const CFGBlock* B, - ExplodedNode* Pred); - void HandleCallEnter(const CallEnter &L, const CFGBlock *Block, - unsigned Index, ExplodedNode *Pred); - void HandleCallExit(const CallExit &L, ExplodedNode *Pred); - - /// Get the initial state from the subengine. - const GRState* getInitialState(const LocationContext *InitLoc) { - return SubEngine.getInitialState(InitLoc); - } - - void ProcessEndPath(GREndPathNodeBuilder& Builder) { - SubEngine.ProcessEndPath(Builder); - } - - void ProcessStmt(const CFGElement E, GRStmtNodeBuilder& Builder) { - SubEngine.ProcessStmt(E, Builder); - } - - bool ProcessBlockEntrance(const CFGBlock* Blk, const ExplodedNode *Pred, - GRBlockCounter BC) { - return SubEngine.ProcessBlockEntrance(Blk, Pred, BC); - } - - - void ProcessBranch(const Stmt* Condition, const Stmt* Terminator, - GRBranchNodeBuilder& Builder) { - SubEngine.ProcessBranch(Condition, Terminator, Builder); - } - - - void ProcessIndirectGoto(GRIndirectGotoNodeBuilder& Builder) { - SubEngine.ProcessIndirectGoto(Builder); - } - - - void ProcessSwitch(GRSwitchNodeBuilder& Builder) { - SubEngine.ProcessSwitch(Builder); - } - - void ProcessCallEnter(GRCallEnterNodeBuilder &Builder) { - SubEngine.ProcessCallEnter(Builder); - } - - void ProcessCallExit(GRCallExitNodeBuilder &Builder) { - SubEngine.ProcessCallExit(Builder); - } - -private: - GRCoreEngine(const GRCoreEngine&); // Do not implement. - GRCoreEngine& operator=(const GRCoreEngine&); - -public: - /// Construct a GRCoreEngine object to analyze the provided CFG using - /// a DFS exploration of the exploded graph. - GRCoreEngine(GRSubEngine& subengine) - : SubEngine(subengine), G(new ExplodedGraph()), - WList(GRWorkList::MakeBFS()), - BCounterFactory(G->getAllocator()) {} - - /// Construct a GRCoreEngine object to analyze the provided CFG and to - /// use the provided worklist object to execute the worklist algorithm. - /// The GRCoreEngine object assumes ownership of 'wlist'. - GRCoreEngine(GRWorkList* wlist, GRSubEngine& subengine) - : SubEngine(subengine), G(new ExplodedGraph()), WList(wlist), - BCounterFactory(G->getAllocator()) {} - - ~GRCoreEngine() { - delete WList; - } - - /// getGraph - Returns the exploded graph. - ExplodedGraph& getGraph() { return *G.get(); } - - /// takeGraph - Returns the exploded graph. Ownership of the graph is - /// transfered to the caller. - ExplodedGraph* takeGraph() { return G.take(); } - - /// ExecuteWorkList - Run the worklist algorithm for a maximum number of - /// steps. Returns true if there is still simulation state on the worklist. - bool ExecuteWorkList(const LocationContext *L, unsigned Steps, - const GRState *InitState); - void ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps, - const GRState *InitState, - ExplodedNodeSet &Dst); - - // Functions for external checking of whether we have unfinished work - bool wasBlockAborted() const { return !blocksAborted.empty(); } - bool hasWorkRemaining() const { return wasBlockAborted() || WList->hasWork(); } - - GRWorkList *getWorkList() const { return WList; } - - BlocksAborted::const_iterator blocks_aborted_begin() const { - return blocksAborted.begin(); - } - BlocksAborted::const_iterator blocks_aborted_end() const { - return blocksAborted.end(); - } -}; - -class GRStmtNodeBuilder { - GRCoreEngine& Eng; - const CFGBlock& B; - const unsigned Idx; - ExplodedNode* Pred; - GRStateManager& Mgr; - GRAuditor* Auditor; - -public: - bool PurgingDeadSymbols; - bool BuildSinks; - bool HasGeneratedNode; - ProgramPoint::Kind PointKind; - const void *Tag; - - const GRState* CleanedState; - - - typedef llvm::SmallPtrSet<ExplodedNode*,5> DeferredTy; - DeferredTy Deferred; - - void GenerateAutoTransition(ExplodedNode* N); - -public: - GRStmtNodeBuilder(const CFGBlock* b, unsigned idx, ExplodedNode* N, - GRCoreEngine* e, GRStateManager &mgr); - - ~GRStmtNodeBuilder(); - - ExplodedNode* getBasePredecessor() const { return Pred; } - - // FIXME: This should not be exposed. - GRWorkList *getWorkList() { return Eng.WList; } - - void SetCleanedState(const GRState* St) { - CleanedState = St; - } - - GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();} - - unsigned getCurrentBlockCount() const { - return getBlockCounter().getNumVisited( - Pred->getLocationContext()->getCurrentStackFrame(), - B.getBlockID()); - } - - ExplodedNode* generateNode(PostStmt PP,const GRState* St,ExplodedNode* Pred) { - HasGeneratedNode = true; - return generateNodeInternal(PP, St, Pred); - } - - ExplodedNode* generateNode(const Stmt *S, const GRState *St, - ExplodedNode *Pred, ProgramPoint::Kind K) { - HasGeneratedNode = true; - - if (PurgingDeadSymbols) - K = ProgramPoint::PostPurgeDeadSymbolsKind; - - return generateNodeInternal(S, St, Pred, K, Tag); - } - - ExplodedNode* generateNode(const Stmt *S, const GRState *St, - ExplodedNode *Pred) { - return generateNode(S, St, Pred, PointKind); - } - - ExplodedNode *generateNode(const ProgramPoint &PP, const GRState* State, - ExplodedNode* Pred) { - HasGeneratedNode = true; - return generateNodeInternal(PP, State, Pred); - } - - ExplodedNode* - generateNodeInternal(const ProgramPoint &PP, const GRState* State, - ExplodedNode* Pred); - - ExplodedNode* - generateNodeInternal(const Stmt* S, const GRState* State, ExplodedNode* Pred, - ProgramPoint::Kind K = ProgramPoint::PostStmtKind, - const void *tag = 0); - - /// getStmt - Return the current block-level expression associated with - /// this builder. - const Stmt* getStmt() const { return B[Idx]; } - - /// getBlock - Return the CFGBlock associated with the block-level expression - /// of this builder. - const CFGBlock* getBlock() const { return &B; } - - unsigned getIndex() const { return Idx; } - - void setAuditor(GRAuditor* A) { Auditor = A; } - - const GRState* GetState(ExplodedNode* Pred) const { - if (Pred == getBasePredecessor()) - return CleanedState; - else - return Pred->getState(); - } - - ExplodedNode* MakeNode(ExplodedNodeSet& Dst, const Stmt* S, - ExplodedNode* Pred, const GRState* St) { - return MakeNode(Dst, S, Pred, St, PointKind); - } - - ExplodedNode* MakeNode(ExplodedNodeSet& Dst, const Stmt* S,ExplodedNode* Pred, - const GRState* St, ProgramPoint::Kind K); - - ExplodedNode* MakeSinkNode(ExplodedNodeSet& Dst, const Stmt* S, - ExplodedNode* Pred, const GRState* St) { - bool Tmp = BuildSinks; - BuildSinks = true; - ExplodedNode* N = MakeNode(Dst, S, Pred, St); - BuildSinks = Tmp; - return N; - } -}; - -class GRBranchNodeBuilder { - GRCoreEngine& Eng; - const CFGBlock* Src; - const CFGBlock* DstT; - const CFGBlock* DstF; - ExplodedNode* Pred; - - typedef llvm::SmallVector<ExplodedNode*,3> DeferredTy; - DeferredTy Deferred; - - bool GeneratedTrue; - bool GeneratedFalse; - bool InFeasibleTrue; - bool InFeasibleFalse; - -public: - GRBranchNodeBuilder(const CFGBlock* src, const CFGBlock* dstT, - const CFGBlock* dstF, ExplodedNode* pred, GRCoreEngine* e) - : Eng(*e), Src(src), DstT(dstT), DstF(dstF), Pred(pred), - GeneratedTrue(false), GeneratedFalse(false), - InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {} - - ~GRBranchNodeBuilder(); - - ExplodedNode* getPredecessor() const { return Pred; } - - const ExplodedGraph& getGraph() const { return *Eng.G; } - - GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();} - - ExplodedNode* generateNode(const GRState* State, bool branch); - - const CFGBlock* getTargetBlock(bool branch) const { - return branch ? DstT : DstF; - } - - void markInfeasible(bool branch) { - if (branch) - InFeasibleTrue = GeneratedTrue = true; - else - InFeasibleFalse = GeneratedFalse = true; - } - - bool isFeasible(bool branch) { - return branch ? !InFeasibleTrue : !InFeasibleFalse; - } - - const GRState* getState() const { - return getPredecessor()->getState(); - } -}; - -class GRIndirectGotoNodeBuilder { - GRCoreEngine& Eng; - const CFGBlock* Src; - const CFGBlock& DispatchBlock; - const Expr* E; - ExplodedNode* Pred; - -public: - GRIndirectGotoNodeBuilder(ExplodedNode* pred, const CFGBlock* src, - const Expr* e, const CFGBlock* dispatch, GRCoreEngine* eng) - : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {} - - class iterator { - CFGBlock::const_succ_iterator I; - - friend class GRIndirectGotoNodeBuilder; - iterator(CFGBlock::const_succ_iterator i) : I(i) {} - public: - - iterator& operator++() { ++I; return *this; } - bool operator!=(const iterator& X) const { return I != X.I; } - - const LabelStmt* getLabel() const { - return llvm::cast<LabelStmt>((*I)->getLabel()); - } - - const CFGBlock* getBlock() const { - return *I; - } - }; - - iterator begin() { return iterator(DispatchBlock.succ_begin()); } - iterator end() { return iterator(DispatchBlock.succ_end()); } - - ExplodedNode* generateNode(const iterator& I, const GRState* State, - bool isSink = false); - - const Expr* getTarget() const { return E; } - - const GRState* getState() const { return Pred->State; } -}; - -class GRSwitchNodeBuilder { - GRCoreEngine& Eng; - const CFGBlock* Src; - const Expr* Condition; - ExplodedNode* Pred; - -public: - GRSwitchNodeBuilder(ExplodedNode* pred, const CFGBlock* src, - const Expr* condition, GRCoreEngine* eng) - : Eng(*eng), Src(src), Condition(condition), Pred(pred) {} - - class iterator { - CFGBlock::const_succ_reverse_iterator I; - - friend class GRSwitchNodeBuilder; - iterator(CFGBlock::const_succ_reverse_iterator i) : I(i) {} - - public: - iterator& operator++() { ++I; return *this; } - bool operator!=(const iterator &X) const { return I != X.I; } - bool operator==(const iterator &X) const { return I == X.I; } - - const CaseStmt* getCase() const { - return llvm::cast<CaseStmt>((*I)->getLabel()); - } - - const CFGBlock* getBlock() const { - return *I; - } - }; - - iterator begin() { return iterator(Src->succ_rbegin()+1); } - iterator end() { return iterator(Src->succ_rend()); } - - ExplodedNode* generateCaseStmtNode(const iterator& I, const GRState* State); - - ExplodedNode* generateDefaultCaseNode(const GRState* State, - bool isSink = false); - - const Expr* getCondition() const { return Condition; } - - const GRState* getState() const { return Pred->State; } -}; - -class GREndPathNodeBuilder { - GRCoreEngine &Eng; - const CFGBlock& B; - ExplodedNode* Pred; - -public: - bool HasGeneratedNode; - -public: - GREndPathNodeBuilder(const CFGBlock* b, ExplodedNode* N, GRCoreEngine* e) - : Eng(*e), B(*b), Pred(N), HasGeneratedNode(false) {} - - ~GREndPathNodeBuilder(); - - GRWorkList &getWorkList() { return *Eng.WList; } - - ExplodedNode* getPredecessor() const { return Pred; } - - GRBlockCounter getBlockCounter() const { - return Eng.WList->getBlockCounter(); - } - - unsigned getCurrentBlockCount() const { - return getBlockCounter().getNumVisited( - Pred->getLocationContext()->getCurrentStackFrame(), - B.getBlockID()); - } - - ExplodedNode* generateNode(const GRState* State, const void *tag = 0, - ExplodedNode *P = 0); - - void GenerateCallExitNode(const GRState *state); - - const CFGBlock* getBlock() const { return &B; } - - const GRState* getState() const { - return getPredecessor()->getState(); - } -}; - -class GRCallEnterNodeBuilder { - GRCoreEngine &Eng; - - const ExplodedNode *Pred; - - // The call site. - const Stmt *CE; - - // The AnalysisContext of the callee. - AnalysisContext *CalleeCtx; - - // The parent block of the CallExpr. - const CFGBlock *Block; - - // The CFGBlock index of the CallExpr. - unsigned Index; - -public: - GRCallEnterNodeBuilder(GRCoreEngine &eng, const ExplodedNode *pred, - const Stmt *s, AnalysisContext *callee, - const CFGBlock *blk, unsigned idx) - : Eng(eng), Pred(pred), CE(s), CalleeCtx(callee), Block(blk), Index(idx) {} - - const GRState *getState() const { return Pred->getState(); } - - const LocationContext *getLocationContext() const { - return Pred->getLocationContext(); - } - - const Stmt *getCallExpr() const { return CE; } - - AnalysisContext *getCalleeContext() const { return CalleeCtx; } - - const CFGBlock *getBlock() const { return Block; } - - unsigned getIndex() const { return Index; } - - void GenerateNode(const GRState *state, const LocationContext *LocCtx); -}; - -class GRCallExitNodeBuilder { - GRCoreEngine &Eng; - const ExplodedNode *Pred; - -public: - GRCallExitNodeBuilder(GRCoreEngine &eng, const ExplodedNode *pred) - : Eng(eng), Pred(pred) {} - - const ExplodedNode *getPredecessor() const { return Pred; } - - const GRState *getState() const { return Pred->getState(); } - - void GenerateNode(const GRState *state); -}; -} // end clang namespace - -#endif diff --git a/include/clang/Checker/PathSensitive/GRExprEngine.h b/include/clang/Checker/PathSensitive/GRExprEngine.h deleted file mode 100644 index 5ba0b36..0000000 --- a/include/clang/Checker/PathSensitive/GRExprEngine.h +++ /dev/null @@ -1,528 +0,0 @@ -//===-- GRExprEngine.h - Path-Sensitive Expression-Level Dataflow ---*- 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 a meta-engine for path-sensitive dataflow analysis that -// is built on GRCoreEngine, but provides the boilerplate to execute transfer -// functions and build the ExplodedGraph at the expression level. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_GREXPRENGINE -#define LLVM_CLANG_ANALYSIS_GREXPRENGINE - -#include "clang/Checker/PathSensitive/AnalysisManager.h" -#include "clang/Checker/PathSensitive/GRSubEngine.h" -#include "clang/Checker/PathSensitive/GRCoreEngine.h" -#include "clang/Checker/PathSensitive/GRState.h" -#include "clang/Checker/PathSensitive/GRSimpleAPICheck.h" -#include "clang/Checker/PathSensitive/GRTransferFuncs.h" -#include "clang/Checker/BugReporter/BugReporter.h" -#include "clang/AST/Type.h" -#include "clang/AST/ExprObjC.h" -#include "clang/AST/ExprCXX.h" - -namespace clang { -class AnalysisManager; -class Checker; -class ObjCForCollectionStmt; - -class GRExprEngine : public GRSubEngine { - AnalysisManager &AMgr; - - GRCoreEngine CoreEngine; - - /// G - the simulation graph. - ExplodedGraph& G; - - /// Builder - The current GRStmtNodeBuilder which is used when building the - /// nodes for a given statement. - GRStmtNodeBuilder* Builder; - - /// StateMgr - Object that manages the data for all created states. - GRStateManager StateMgr; - - /// SymMgr - Object that manages the symbol information. - SymbolManager& SymMgr; - - /// ValMgr - Object that manages/creates SVals. - ValueManager &ValMgr; - - /// SVator - SValuator object that creates SVals from expressions. - SValuator &SVator; - - /// EntryNode - The immediate predecessor node. - ExplodedNode* EntryNode; - - /// CleanedState - The state for EntryNode "cleaned" of all dead - /// variables and symbols (as determined by a liveness analysis). - const GRState* CleanedState; - - /// CurrentStmt - The current block-level statement. - const Stmt* CurrentStmt; - - // Obj-C Class Identifiers. - IdentifierInfo* NSExceptionII; - - // Obj-C Selectors. - Selector* NSExceptionInstanceRaiseSelectors; - Selector RaiseSel; - - llvm::OwningPtr<GRSimpleAPICheck> BatchAuditor; - - 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 GRExprEngine is destroyed. - GRBugReporter BR; - - llvm::OwningPtr<GRTransferFuncs> TF; - - class CallExprWLItem { - public: - CallExpr::const_arg_iterator I; - ExplodedNode *N; - - CallExprWLItem(const CallExpr::const_arg_iterator &i, ExplodedNode *n) - : I(i), N(n) {} - }; - -public: - GRExprEngine(AnalysisManager &mgr, GRTransferFuncs *tf); - - ~GRExprEngine(); - - void ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) { - CoreEngine.ExecuteWorkList(L, Steps, 0); - } - - /// Execute the work list with an initial state. Nodes that reaches the exit - /// of the function are added into the Dst set, which represent the exit - /// state of the function call. - void ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps, - const GRState *InitState, - ExplodedNodeSet &Dst) { - CoreEngine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst); - } - - /// getContext - Return the ASTContext associated with this analysis. - ASTContext& getContext() const { return AMgr.getASTContext(); } - - virtual AnalysisManager &getAnalysisManager() { return AMgr; } - - SValuator &getSValuator() { return SVator; } - - GRTransferFuncs& getTF() { return *TF; } - - BugReporter& getBugReporter() { return BR; } - - GRStmtNodeBuilder &getBuilder() { assert(Builder); return *Builder; } - - // FIXME: Remove once GRTransferFuncs is no longer referenced. - void setTransferFunction(GRTransferFuncs* tf); - - /// ViewGraph - Visualize the ExplodedGraph created by executing the - /// simulation. - void ViewGraph(bool trim = false); - - void ViewGraph(ExplodedNode** Beg, ExplodedNode** End); - - /// getInitialState - Return the initial state used for the root vertex - /// in the ExplodedGraph. - const GRState* getInitialState(const LocationContext *InitLoc); - - 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())); - } - - void AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C); - void AddCheck(GRSimpleAPICheck* A); - - /// ProcessStmt - Called by GRCoreEngine. Used to generate new successor - /// nodes by processing the 'effects' of a block-level statement. - void ProcessStmt(const CFGElement E, GRStmtNodeBuilder& builder); - - /// ProcessBlockEntrance - Called by GRCoreEngine when start processing - /// a CFGBlock. This method returns true if the analysis should continue - /// exploring the given path, and false otherwise. - bool ProcessBlockEntrance(const CFGBlock* B, const ExplodedNode *Pred, - GRBlockCounter BC); - - /// ProcessBranch - Called by GRCoreEngine. Used to generate successor - /// nodes by processing the 'effects' of a branch condition. - void ProcessBranch(const Stmt* Condition, const Stmt* Term, - GRBranchNodeBuilder& builder); - - /// ProcessIndirectGoto - Called by GRCoreEngine. Used to generate successor - /// nodes by processing the 'effects' of a computed goto jump. - void ProcessIndirectGoto(GRIndirectGotoNodeBuilder& builder); - - /// ProcessSwitch - Called by GRCoreEngine. Used to generate successor - /// nodes by processing the 'effects' of a switch statement. - void ProcessSwitch(GRSwitchNodeBuilder& builder); - - /// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path - /// nodes when the control reaches the end of a function. - void ProcessEndPath(GREndPathNodeBuilder& builder); - - /// Generate the entry node of the callee. - void ProcessCallEnter(GRCallEnterNodeBuilder &builder); - - /// Generate the first post callsite node. - void ProcessCallExit(GRCallExitNodeBuilder &builder); - - /// Called by GRCoreEngine when the analysis worklist has terminated. - void ProcessEndWorklist(bool hasWorkRemaining); - - /// EvalAssume - Callback function invoked by the ConstraintManager when - /// making assumptions about state values. - const GRState *ProcessAssume(const GRState *state, SVal cond,bool assumption); - - /// WantsRegionChangeUpdate - Called by GRStateManager to determine if a - /// region change should trigger a ProcessRegionChanges update. - bool WantsRegionChangeUpdate(const GRState* state); - - /// ProcessRegionChanges - Called by GRStateManager whenever a change is made - /// to the store. Used to update checkers that track region values. - const GRState* ProcessRegionChanges(const GRState *state, - const MemRegion * const *Begin, - const MemRegion * const *End); - - virtual GRStateManager& getStateManager() { return StateMgr; } - - StoreManager& getStoreManager() { return StateMgr.getStoreManager(); } - - ConstraintManager& getConstraintManager() { - return StateMgr.getConstraintManager(); - } - - // FIXME: Remove when we migrate over to just using ValueManager. - BasicValueFactory& getBasicVals() { - return StateMgr.getBasicVals(); - } - const BasicValueFactory& getBasicVals() const { - return StateMgr.getBasicVals(); - } - - ValueManager &getValueManager() { return ValMgr; } - const ValueManager &getValueManager() const { return ValMgr; } - - // FIXME: Remove when we migrate over to just using ValueManager. - SymbolManager& getSymbolManager() { return SymMgr; } - const SymbolManager& getSymbolManager() const { return SymMgr; } - - // Functions for external checking of whether we have unfinished work - bool wasBlockAborted() const { return CoreEngine.wasBlockAborted(); } - bool hasWorkRemaining() const { - return wasBlockAborted() || CoreEngine.getWorkList()->hasWork(); - } - - const GRCoreEngine &getCoreEngine() const { return CoreEngine; } - -protected: - const GRState* GetState(ExplodedNode* N) { - return N == EntryNode ? CleanedState : N->getState(); - } - -public: - ExplodedNode* MakeNode(ExplodedNodeSet& Dst, const Stmt* S, - ExplodedNode* Pred, const GRState* St, - 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); - - bool CheckerEvalCall(const CallExpr *CE, - ExplodedNodeSet &Dst, - ExplodedNode *Pred); - - void CheckerEvalNilReceiver(const ObjCMessageExpr *ME, - 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); - - /// VisitLValue - Evaluate the lvalue of the expression. For example, if Ex is - /// a DeclRefExpr, it evaluates to the MemRegionVal which represents its - /// storage location. Note that not all kinds of expressions has lvalue. - void VisitLValue(const Expr* Ex, ExplodedNode* Pred, ExplodedNodeSet& Dst); - - /// VisitArraySubscriptExpr - Transfer function for array accesses. - void VisitArraySubscriptExpr(const ArraySubscriptExpr* Ex, ExplodedNode* Pred, - ExplodedNodeSet& Dst, bool asLValue); - - /// VisitAsmStmt - Transfer function logic for inline asm. - void VisitAsmStmt(const AsmStmt* A, ExplodedNode* Pred, ExplodedNodeSet& Dst); - - void VisitAsmStmtHelperOutputs(const AsmStmt* A, - AsmStmt::const_outputs_iterator I, - AsmStmt::const_outputs_iterator E, - ExplodedNode* Pred, ExplodedNodeSet& Dst); - - void VisitAsmStmtHelperInputs(const AsmStmt* A, - AsmStmt::const_inputs_iterator I, - AsmStmt::const_inputs_iterator E, - ExplodedNode* Pred, ExplodedNodeSet& Dst); - - /// VisitBlockExpr - Transfer function logic for BlockExprs. - void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, - ExplodedNodeSet &Dst); - - /// VisitBinaryOperator - Transfer function logic for binary operators. - void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode* Pred, - ExplodedNodeSet& Dst, bool asLValue); - - - /// 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, bool asLValue); - - /// VisitCast - Transfer function logic for all casts (implicit and explicit). - void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, - ExplodedNodeSet &Dst, bool asLValue); - - /// VisitCompoundLiteralExpr - Transfer function logic for compound literals. - void VisitCompoundLiteralExpr(const CompoundLiteralExpr* CL, - ExplodedNode* Pred, ExplodedNodeSet& Dst, - bool asLValue); - - /// VisitDeclRefExpr - Transfer function logic for DeclRefExprs. - void VisitDeclRefExpr(const DeclRefExpr* DR, ExplodedNode* Pred, - ExplodedNodeSet& Dst, bool asLValue); - - /// VisitBlockDeclRefExpr - Transfer function logic for BlockDeclRefExprs. - void VisitBlockDeclRefExpr(const BlockDeclRefExpr* DR, ExplodedNode* Pred, - ExplodedNodeSet& Dst, bool asLValue); - - void VisitCommonDeclRefExpr(const Expr* DR, const NamedDecl *D, - ExplodedNode* Pred, ExplodedNodeSet& Dst, - bool asLValue); - - /// VisitDeclStmt - Transfer function logic for DeclStmts. - void VisitDeclStmt(const DeclStmt* DS, ExplodedNode* Pred, - ExplodedNodeSet& Dst); - - /// 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); - - /// VisitLogicalExpr - Transfer function logic for '&&', '||' - void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode* Pred, - ExplodedNodeSet& Dst); - - /// VisitMemberExpr - Transfer function for member expressions. - void VisitMemberExpr(const MemberExpr* M, ExplodedNode* Pred, - ExplodedNodeSet& Dst, bool asLValue); - - /// VisitObjCIvarRefExpr - Transfer function logic for ObjCIvarRefExprs. - void VisitObjCIvarRefExpr(const ObjCIvarRefExpr* DR, ExplodedNode* Pred, - ExplodedNodeSet& Dst, bool asLValue); - - /// VisitObjCForCollectionStmt - Transfer function logic for - /// ObjCForCollectionStmt. - void VisitObjCForCollectionStmt(const ObjCForCollectionStmt* S, - ExplodedNode* Pred, ExplodedNodeSet& Dst); - - void VisitObjCForCollectionStmtAux(const ObjCForCollectionStmt* S, - ExplodedNode* Pred, - ExplodedNodeSet& Dst, SVal ElementV); - - /// VisitObjCMessageExpr - Transfer function for ObjC message expressions. - void VisitObjCMessageExpr(const ObjCMessageExpr* ME, ExplodedNode* Pred, - ExplodedNodeSet& Dst, bool asLValue); - - /// VisitReturnStmt - Transfer function logic for return statements. - void VisitReturnStmt(const ReturnStmt* R, ExplodedNode* Pred, - ExplodedNodeSet& Dst); - - /// VisitOffsetOfExpr - Transfer function for offsetof. - void VisitOffsetOfExpr(const OffsetOfExpr* Ex, ExplodedNode* Pred, - ExplodedNodeSet& Dst); - - /// VisitSizeOfAlignOfExpr - Transfer function for sizeof. - void VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr* Ex, ExplodedNode* Pred, - ExplodedNodeSet& Dst); - - /// VisitUnaryOperator - Transfer function logic for unary operators. - void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode* Pred, - ExplodedNodeSet& Dst, bool asLValue); - - void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, - ExplodedNodeSet & Dst); - - void VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest, - ExplodedNode *Pred, - ExplodedNodeSet &Dst); - - void VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, ExplodedNode *Pred, - ExplodedNodeSet &Dst); - - void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, - ExplodedNodeSet &Dst); - - void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, - ExplodedNodeSet &Dst); - - void VisitAggExpr(const Expr *E, SVal Dest, ExplodedNode *Pred, - ExplodedNodeSet &Dst); - - /// Create a C++ temporary object for an rvalue. - void CreateCXXTemporaryObject(const Expr *Ex, ExplodedNode *Pred, - ExplodedNodeSet &Dst); - - /// Synthesize CXXThisRegion. - const CXXThisRegion *getCXXThisRegion(const CXXMethodDecl *MD, - const StackFrameContext *SFC); - - /// Evaluate arguments with a work list algorithm. - void EvalArguments(ConstExprIterator AI, ConstExprIterator AE, - const FunctionProtoType *FnType, - ExplodedNode *Pred, ExplodedNodeSet &Dst); - - /// EvalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic - /// expressions of the form 'x != 0' and generate new nodes (stored in Dst) - /// with those assumptions. - void EvalEagerlyAssume(ExplodedNodeSet& Dst, ExplodedNodeSet& Src, - const Expr *Ex); - - SVal EvalMinus(SVal X) { - return X.isValid() ? SVator.EvalMinus(cast<NonLoc>(X)) : X; - } - - SVal EvalComplement(SVal X) { - return X.isValid() ? SVator.EvalComplement(cast<NonLoc>(X)) : X; - } - -public: - - SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op, - NonLoc L, NonLoc R, QualType T) { - return SVator.EvalBinOpNN(state, op, L, R, T); - } - - SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op, - NonLoc L, SVal R, QualType T) { - return R.isValid() ? SVator.EvalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R; - } - - SVal EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op, - SVal LHS, SVal RHS, QualType T) { - return SVator.EvalBinOp(ST, Op, LHS, RHS, T); - } - -protected: - void EvalObjCMessageExpr(ExplodedNodeSet& Dst, const ObjCMessageExpr* ME, - ExplodedNode* Pred, const GRState *state) { - assert (Builder && "GRStmtNodeBuilder must be defined."); - getTF().EvalObjCMessageExpr(Dst, *this, *Builder, ME, Pred, state); - } - - const GRState* MarkBranch(const GRState* St, const Stmt* Terminator, - bool branchTaken); - - /// EvalBind - Handle the semantics of binding a value to a specific location. - /// This method is used by EvalStore, VisitDeclStmt, and others. - void EvalBind(ExplodedNodeSet& Dst, const Stmt* StoreE, ExplodedNode* Pred, - const GRState* St, SVal location, SVal Val, - bool atDeclInit = false); - -public: - // FIXME: 'tag' should be removed, and a LocationContext should be used - // instead. - void EvalLoad(ExplodedNodeSet& Dst, const Expr* Ex, ExplodedNode* Pred, - const GRState* St, SVal location, const void *tag = 0, - QualType LoadTy = QualType()); - - // FIXME: 'tag' should be removed, and a LocationContext should be used - // instead. - void EvalStore(ExplodedNodeSet& Dst, const Expr* AssignE, const Expr* StoreE, - ExplodedNode* Pred, const GRState* St, SVal TargetLV, SVal Val, - const void *tag = 0); -private: - void EvalLoadCommon(ExplodedNodeSet& Dst, const Expr* Ex, ExplodedNode* Pred, - const GRState* St, SVal location, const void *tag, - QualType LoadTy); - - // FIXME: 'tag' should be removed, and a LocationContext should be used - // instead. - void EvalLocation(ExplodedNodeSet &Dst, const Stmt *S, ExplodedNode* Pred, - const GRState* St, SVal location, - const void *tag, bool isLoad); - - bool InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, ExplodedNode *Pred); -}; - -} // end clang namespace - -#endif diff --git a/include/clang/Checker/PathSensitive/GRExprEngineBuilders.h b/include/clang/Checker/PathSensitive/GRExprEngineBuilders.h deleted file mode 100644 index 5503412..0000000 --- a/include/clang/Checker/PathSensitive/GRExprEngineBuilders.h +++ /dev/null @@ -1,76 +0,0 @@ -//===-- GRExprEngineBuilders.h - "Builder" classes for GRExprEngine -*- 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 smart builder "references" which are used to marshal -// builders between GRExprEngine objects and their related components. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_GREXPRENGINE_BUILDERS -#define LLVM_CLANG_ANALYSIS_GREXPRENGINE_BUILDERS -#include "clang/Checker/PathSensitive/GRExprEngine.h" -#include "clang/Analysis/Support/SaveAndRestore.h" - -namespace clang { - -class GRStmtNodeBuilderRef { - ExplodedNodeSet &Dst; - GRStmtNodeBuilder &B; - GRExprEngine& Eng; - ExplodedNode* Pred; - const GRState* state; - const Stmt* stmt; - const unsigned OldSize; - const bool AutoCreateNode; - SaveAndRestore<bool> OldSink; - SaveAndRestore<const void*> OldTag; - SaveOr OldHasGen; - -private: - friend class GRExprEngine; - - GRStmtNodeBuilderRef(); // do not implement - void operator=(const GRStmtNodeBuilderRef&); // do not implement - - GRStmtNodeBuilderRef(ExplodedNodeSet &dst, - GRStmtNodeBuilder &builder, - GRExprEngine& eng, - ExplodedNode* pred, - const GRState *st, - const Stmt* s, bool auto_create_node) - : Dst(dst), B(builder), Eng(eng), Pred(pred), - state(st), stmt(s), OldSize(Dst.size()), AutoCreateNode(auto_create_node), - OldSink(B.BuildSinks), OldTag(B.Tag), OldHasGen(B.HasGeneratedNode) {} - -public: - - ~GRStmtNodeBuilderRef() { - // Handle the case where no nodes where generated. Auto-generate that - // contains the updated state if we aren't generating sinks. - if (!B.BuildSinks && Dst.size() == OldSize && !B.HasGeneratedNode) { - if (AutoCreateNode) - B.MakeNode(Dst, const_cast<Stmt*>(stmt), Pred, state); - else - Dst.Add(Pred); - } - } - - const GRState *getState() { return state; } - - GRStateManager& getStateManager() { - return Eng.getStateManager(); - } - - ExplodedNode* MakeNode(const GRState* state) { - return B.MakeNode(Dst, const_cast<Stmt*>(stmt), Pred, state); - } -}; - -} // end clang namespace -#endif diff --git a/include/clang/Checker/PathSensitive/GRSimpleAPICheck.h b/include/clang/Checker/PathSensitive/GRSimpleAPICheck.h deleted file mode 100644 index 6d85e5f..0000000 --- a/include/clang/Checker/PathSensitive/GRSimpleAPICheck.h +++ /dev/null @@ -1,31 +0,0 @@ -// GRCheckAPI.h - Simple API checks based on GRAuditor ------------*- C++ -*--// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the interface for building simple, path-sensitive checks -// that are stateless and only emit warnings at errors that occur at -// CallExpr or ObjCMessageExpr. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_GRAPICHECKS -#define LLVM_CLANG_ANALYSIS_GRAPICHECKS - -#include "clang/Checker/PathSensitive/GRAuditor.h" - -namespace clang { - -class GRSimpleAPICheck : public GRAuditor { -public: - GRSimpleAPICheck() {} - virtual ~GRSimpleAPICheck() {} -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Checker/PathSensitive/GRState.h b/include/clang/Checker/PathSensitive/GRState.h deleted file mode 100644 index d72d63a..0000000 --- a/include/clang/Checker/PathSensitive/GRState.h +++ /dev/null @@ -1,760 +0,0 @@ -//== GRState*h - Path-Sens. "State" for tracking valuues -----*- 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 SymbolRef, ExprBindKey, and GRState* -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_VALUESTATE_H -#define LLVM_CLANG_ANALYSIS_VALUESTATE_H - -#include "clang/Checker/PathSensitive/ConstraintManager.h" -#include "clang/Checker/PathSensitive/Environment.h" -#include "clang/Checker/PathSensitive/Store.h" -#include "clang/Checker/PathSensitive/ValueManager.h" -#include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/ImmutableMap.h" -#include "llvm/Support/Casting.h" - -namespace llvm { -class APSInt; -class BumpPtrAllocator; -class raw_ostream; -} - -namespace clang { -class ASTContext; -class GRStateManager; -class Checker; - -typedef ConstraintManager* (*ConstraintManagerCreator)(GRStateManager&, - GRSubEngine&); -typedef StoreManager* (*StoreManagerCreator)(GRStateManager&); - -//===----------------------------------------------------------------------===// -// GRStateTrait - Traits used by the Generic Data Map of a GRState. -//===----------------------------------------------------------------------===// - -template <typename T> struct GRStatePartialTrait; - -template <typename T> struct GRStateTrait { - typedef typename T::data_type data_type; - static inline void* GDMIndex() { return &T::TagInt; } - static inline void* MakeVoidPtr(data_type D) { return (void*) D; } - static inline data_type MakeData(void* const* P) { - return P ? (data_type) *P : (data_type) 0; - } -}; - -//===----------------------------------------------------------------------===// -// GRState- An ImmutableMap type Stmt*/Decl*/Symbols to SVals. -//===----------------------------------------------------------------------===// - -class GRStateManager; - -/// GRState - This class encapsulates the actual data values for -/// for a "state" in our symbolic value tracking. It is intended to be -/// used as a functional object; that is once it is created and made -/// "persistent" in a FoldingSet its values will never change. -class GRState : public llvm::FoldingSetNode { -public: - typedef llvm::ImmutableSet<llvm::APSInt*> IntSetTy; - typedef llvm::ImmutableMap<void*, void*> GenericDataMap; - -private: - void operator=(const GRState& R) const; // Do not implement. - - friend class GRStateManager; - - GRStateManager *StateMgr; - Environment Env; - Store St; - GenericDataMap GDM; - - /// makeWithStore - Return a GRState with the same values as the current - /// state with the exception of using the specified Store. - const GRState *makeWithStore(Store store) const; - -public: - - /// This ctor is used when creating the first GRState object. - GRState(GRStateManager *mgr, const Environment& env, - Store st, GenericDataMap gdm) - : StateMgr(mgr), - Env(env), - St(st), - GDM(gdm) {} - - /// Copy ctor - We must explicitly define this or else the "Next" ptr - /// in FoldingSetNode will also get copied. - GRState(const GRState& RHS) - : llvm::FoldingSetNode(), - StateMgr(RHS.StateMgr), - Env(RHS.Env), - St(RHS.St), - GDM(RHS.GDM) {} - - /// getStateManager - Return the GRStateManager associated with this state. - GRStateManager &getStateManager() const { - return *StateMgr; - } - - /// getEnvironment - Return the environment associated with this state. - /// The environment is the mapping from expressions to values. - const Environment& getEnvironment() const { return Env; } - - /// getStore - Return the store associated with this state. The store - /// is a mapping from locations to values. - Store getStore() const { return St; } - - void setStore(Store s) { St = s; } - - /// getGDM - Return the generic data map associated with this state. - GenericDataMap getGDM() const { return GDM; } - - void setGDM(GenericDataMap gdm) { GDM = gdm; } - - /// Profile - Profile the contents of a GRState object for use - /// in a FoldingSet. - static void Profile(llvm::FoldingSetNodeID& ID, const GRState* V) { - V->Env.Profile(ID); - ID.AddPointer(V->St); - V->GDM.Profile(ID); - } - - /// Profile - Used to profile the contents of this object for inclusion - /// in a FoldingSet. - void Profile(llvm::FoldingSetNodeID& ID) const { - Profile(ID, this); - } - - SVal LookupExpr(Expr* E) const { - return Env.LookupExpr(E); - } - - BasicValueFactory &getBasicVals() const; - SymbolManager &getSymbolManager() const; - - //==---------------------------------------------------------------------==// - // Constraints on values. - //==---------------------------------------------------------------------==// - // - // Each GRState records constraints on symbolic values. These constraints - // are managed using the ConstraintManager associated with a GRStateManager. - // As constraints gradually accrue on symbolic values, added constraints - // may conflict and indicate that a state is infeasible (as no real values - // could satisfy all the constraints). This is the principal mechanism - // for modeling path-sensitivity in GRExprEngine/GRState. - // - // Various "Assume" methods form the interface for adding constraints to - // symbolic values. A call to "Assume" indicates an assumption being placed - // on one or symbolic values. Assume methods take the following inputs: - // - // (1) A GRState object representing the current state. - // - // (2) The assumed constraint (which is specific to a given "Assume" method). - // - // (3) A binary value "Assumption" that indicates whether the constraint is - // assumed to be true or false. - // - // The output of "Assume" are two values: - // - // (a) "isFeasible" is set to true or false to indicate whether or not - // the assumption is feasible. - // - // (b) A new GRState object with the added constraints. - // - // FIXME: (a) should probably disappear since it is redundant with (b). - // (i.e., (b) could just be set to NULL). - // - - const GRState *Assume(DefinedOrUnknownSVal cond, bool assumption) const; - - std::pair<const GRState*, const GRState*> - Assume(DefinedOrUnknownSVal cond) const; - - const GRState *AssumeInBound(DefinedOrUnknownSVal idx, - DefinedOrUnknownSVal upperBound, - bool assumption) const; - - //==---------------------------------------------------------------------==// - // Utility methods for getting regions. - //==---------------------------------------------------------------------==// - - const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const; - - //==---------------------------------------------------------------------==// - // Binding and retrieving values to/from the environment and symbolic store. - //==---------------------------------------------------------------------==// - - /// BindCompoundLiteral - Return the state that has the bindings currently - /// in 'state' plus the bindings for the CompoundLiteral. 'R' is the region - /// for the compound literal and 'BegInit' and 'EndInit' represent an - /// array of initializer values. - const GRState *bindCompoundLiteral(const CompoundLiteralExpr* CL, - const LocationContext *LC, - SVal V) const; - - /// Create a new state by binding the value 'V' to the statement 'S' in the - /// state's environment. - const GRState *BindExpr(const Stmt *S, SVal V, bool Invalidate = true) const; - - /// Create a new state by binding the value 'V' and location 'locaton' to the - /// statement 'S' in the state's environment. - const GRState *bindExprAndLocation(const Stmt *S, SVal location, SVal V) - const; - - const GRState *bindDecl(const VarRegion *VR, SVal V) const; - - const GRState *bindDeclWithNoInit(const VarRegion *VR) const; - - const GRState *bindLoc(Loc location, SVal V) const; - - const GRState *bindLoc(SVal location, SVal V) const; - - const GRState *bindDefault(SVal loc, SVal V) const; - - const GRState *unbindLoc(Loc LV) const; - - /// InvalidateRegion - Returns the state with bindings for the given region - /// cleared from the store. See InvalidateRegions. - const GRState *InvalidateRegion(const MemRegion *R, - const Expr *E, unsigned BlockCount, - StoreManager::InvalidatedSymbols *IS = NULL) - const { - return InvalidateRegions(&R, &R+1, E, BlockCount, IS, false); - } - - /// InvalidateRegions - Returns the state with bindings for the given regions - /// cleared from the store. The regions are provided as a continuous array - /// from Begin to End. Optionally invalidates global regions as well. - const GRState *InvalidateRegions(const MemRegion * const *Begin, - const MemRegion * const *End, - const Expr *E, unsigned BlockCount, - StoreManager::InvalidatedSymbols *IS, - bool invalidateGlobals) const; - - /// EnterStackFrame - Returns the state for entry to the given stack frame, - /// preserving the current state. - const GRState *EnterStackFrame(const StackFrameContext *frame) const; - - /// Get the lvalue for a variable reference. - Loc getLValue(const VarDecl *D, const LocationContext *LC) const; - - /// Get the lvalue for a StringLiteral. - Loc getLValue(const StringLiteral *literal) const; - - Loc getLValue(const CompoundLiteralExpr *literal, - const LocationContext *LC) const; - - /// Get the lvalue for an ivar reference. - SVal getLValue(const ObjCIvarDecl *decl, SVal base) const; - - /// Get the lvalue for a field reference. - SVal getLValue(const FieldDecl *decl, SVal Base) const; - - /// Get the lvalue for an array index. - SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const; - - 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 getSValAsScalarOrLoc(const Stmt *Ex) const; - - SVal getSVal(Loc LV, QualType T = QualType()) const; - - /// Returns a "simplified" SVal bound to the location 'LV' in the state's - /// store. A simplified SVal will include optimizations such as - /// if the SVal is a symbol whose value is perfectly constrained then that - /// constant value is returned instead. - SVal getSimplifiedSVal(Loc LV, QualType T= QualType()) const; - - SVal getSVal(const MemRegion* R) const; - - 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, - SymbolVisitor &visitor) const; - - bool scanReachableSymbols(const MemRegion * const *I, - const MemRegion * const *E, - SymbolVisitor &visitor) const; - - template <typename CB> CB scanReachableSymbols(SVal val) const; - template <typename CB> CB scanReachableSymbols(const SVal *beg, - const SVal *end) const; - - template <typename CB> CB - scanReachableSymbols(const MemRegion * const *beg, - const MemRegion * const *end) const; - - //==---------------------------------------------------------------------==// - // Accessing the Generic Data Map (GDM). - //==---------------------------------------------------------------------==// - - void* const* FindGDM(void* K) const; - - template<typename T> - const GRState *add(typename GRStateTrait<T>::key_type K) const; - - template <typename T> - typename GRStateTrait<T>::data_type - get() const { - return GRStateTrait<T>::MakeData(FindGDM(GRStateTrait<T>::GDMIndex())); - } - - template<typename T> - typename GRStateTrait<T>::lookup_type - get(typename GRStateTrait<T>::key_type key) const { - void* const* d = FindGDM(GRStateTrait<T>::GDMIndex()); - return GRStateTrait<T>::Lookup(GRStateTrait<T>::MakeData(d), key); - } - - template <typename T> - typename GRStateTrait<T>::context_type get_context() const; - - - template<typename T> - const GRState *remove(typename GRStateTrait<T>::key_type K) const; - - template<typename T> - const GRState *remove(typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::context_type C) const; - template <typename T> - const GRState *remove() const; - - template<typename T> - const GRState *set(typename GRStateTrait<T>::data_type D) const; - - template<typename T> - const GRState *set(typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::value_type E) const; - - template<typename T> - const GRState *set(typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::value_type E, - typename GRStateTrait<T>::context_type C) const; - - template<typename T> - bool contains(typename GRStateTrait<T>::key_type key) const { - void* const* d = FindGDM(GRStateTrait<T>::GDMIndex()); - return GRStateTrait<T>::Contains(GRStateTrait<T>::MakeData(d), key); - } - - // State pretty-printing. - class Printer { - public: - virtual ~Printer() {} - virtual void Print(llvm::raw_ostream& Out, const GRState* state, - const char* nl, const char* sep) = 0; - }; - - // Pretty-printing. - void print(llvm::raw_ostream& Out, CFG &C, const char *nl = "\n", - const char *sep = "") const; - - void printStdErr(CFG &C) const; - - void printDOT(llvm::raw_ostream& Out, CFG &C) const; -}; - -class GRStateSet { - typedef llvm::SmallPtrSet<const GRState*,5> ImplTy; - ImplTy Impl; -public: - GRStateSet() {} - - inline void Add(const GRState* St) { - Impl.insert(St); - } - - typedef ImplTy::const_iterator iterator; - - inline unsigned size() const { return Impl.size(); } - inline bool empty() const { return Impl.empty(); } - - inline iterator begin() const { return Impl.begin(); } - inline iterator end() const { return Impl.end(); } - - class AutoPopulate { - GRStateSet& S; - unsigned StartSize; - const GRState* St; - public: - AutoPopulate(GRStateSet& s, const GRState* st) - : S(s), StartSize(S.size()), St(st) {} - - ~AutoPopulate() { - if (StartSize == S.size()) - S.Add(St); - } - }; -}; - -//===----------------------------------------------------------------------===// -// GRStateManager - Factory object for GRStates. -//===----------------------------------------------------------------------===// - -class GRStateManager { - friend class GRState; - friend class GRExprEngine; // FIXME: Remove. -private: - /// Eng - The GRSubEngine that owns this state manager. - GRSubEngine &Eng; - - EnvironmentManager EnvMgr; - llvm::OwningPtr<StoreManager> StoreMgr; - llvm::OwningPtr<ConstraintManager> ConstraintMgr; - - GRState::GenericDataMap::Factory GDMFactory; - - typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy; - GDMContextsTy GDMContexts; - - /// Printers - A set of printer objects used for pretty-printing a GRState. - /// GRStateManager owns these objects. - std::vector<GRState::Printer*> Printers; - - /// StateSet - FoldingSet containing all the states created for analyzing - /// a particular function. This is used to unique states. - llvm::FoldingSet<GRState> StateSet; - - /// ValueMgr - Object that manages the data for all created SVals. - ValueManager ValueMgr; - - /// Alloc - A BumpPtrAllocator to allocate states. - llvm::BumpPtrAllocator &Alloc; - -public: - GRStateManager(ASTContext& Ctx, - StoreManagerCreator CreateStoreManager, - ConstraintManagerCreator CreateConstraintManager, - llvm::BumpPtrAllocator& alloc, - GRSubEngine &subeng) - : Eng(subeng), - EnvMgr(alloc), - GDMFactory(alloc), - ValueMgr(alloc, Ctx, *this), - Alloc(alloc) { - StoreMgr.reset((*CreateStoreManager)(*this)); - ConstraintMgr.reset((*CreateConstraintManager)(*this, subeng)); - } - - ~GRStateManager(); - - const GRState *getInitialState(const LocationContext *InitLoc); - - ASTContext &getContext() { return ValueMgr.getContext(); } - const ASTContext &getContext() const { return ValueMgr.getContext(); } - - BasicValueFactory &getBasicVals() { - return ValueMgr.getBasicValueFactory(); - } - const BasicValueFactory& getBasicVals() const { - return ValueMgr.getBasicValueFactory(); - } - - SymbolManager &getSymbolManager() { - return ValueMgr.getSymbolManager(); - } - const SymbolManager &getSymbolManager() const { - return ValueMgr.getSymbolManager(); - } - - ValueManager &getValueManager() { return ValueMgr; } - const ValueManager &getValueManager() const { return ValueMgr; } - - llvm::BumpPtrAllocator& getAllocator() { return Alloc; } - - MemRegionManager& getRegionManager() { - return ValueMgr.getRegionManager(); - } - const MemRegionManager& getRegionManager() const { - return ValueMgr.getRegionManager(); - } - - StoreManager& getStoreManager() { return *StoreMgr; } - ConstraintManager& getConstraintManager() { return *ConstraintMgr; } - GRSubEngine& getOwningEngine() { return Eng; } - - const GRState* RemoveDeadBindings(const GRState* St, - const StackFrameContext *LCtx, - SymbolReaper& SymReaper); - - /// Marshal a new state for the callee in another translation unit. - /// 'state' is owned by the caller's engine. - const GRState *MarshalState(const GRState *state, const StackFrameContext *L); - -public: - - SVal ArrayToPointer(Loc Array) { - return StoreMgr->ArrayToPointer(Array); - } - - // Methods that manipulate the GDM. - const GRState* addGDM(const GRState* St, void* Key, void* Data); - const GRState *removeGDM(const GRState *state, void *Key); - - // Methods that query & manipulate the Store. - - void iterBindings(const GRState* state, StoreManager::BindingsHandler& F) { - StoreMgr->iterBindings(state->getStore(), F); - } - - const GRState* getPersistentState(GRState& Impl); - - //==---------------------------------------------------------------------==// - // Generic Data Map methods. - //==---------------------------------------------------------------------==// - // - // GRStateManager and GRState support a "generic data map" that allows - // different clients of GRState objects to embed arbitrary data within a - // GRState object. The generic data map is essentially an immutable map - // from a "tag" (that acts as the "key" for a client) and opaque values. - // Tags/keys and values are simply void* values. The typical way that clients - // generate unique tags are by taking the address of a static variable. - // Clients are responsible for ensuring that data values referred to by a - // the data pointer are immutable (and thus are essentially purely functional - // data). - // - // The templated methods below use the GRStateTrait<T> class - // to resolve keys into the GDM and to return data values to clients. - // - - // Trait based GDM dispatch. - template <typename T> - const GRState* set(const GRState* st, typename GRStateTrait<T>::data_type D) { - return addGDM(st, GRStateTrait<T>::GDMIndex(), - GRStateTrait<T>::MakeVoidPtr(D)); - } - - template<typename T> - const GRState* set(const GRState* st, - typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::value_type V, - typename GRStateTrait<T>::context_type C) { - - return addGDM(st, GRStateTrait<T>::GDMIndex(), - GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Set(st->get<T>(), K, V, C))); - } - - template <typename T> - const GRState* add(const GRState* st, - typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::context_type C) { - return addGDM(st, GRStateTrait<T>::GDMIndex(), - GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Add(st->get<T>(), K, C))); - } - - template <typename T> - const GRState* remove(const GRState* st, - typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::context_type C) { - - return addGDM(st, GRStateTrait<T>::GDMIndex(), - GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Remove(st->get<T>(), K, C))); - } - - template <typename T> - const GRState *remove(const GRState *st) { - return removeGDM(st, GRStateTrait<T>::GDMIndex()); - } - - void* FindGDMContext(void* index, - void* (*CreateContext)(llvm::BumpPtrAllocator&), - void (*DeleteContext)(void*)); - - template <typename T> - typename GRStateTrait<T>::context_type get_context() { - void* p = FindGDMContext(GRStateTrait<T>::GDMIndex(), - GRStateTrait<T>::CreateContext, - GRStateTrait<T>::DeleteContext); - - return GRStateTrait<T>::MakeContext(p); - } - - const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym) { - return ConstraintMgr->getSymVal(St, sym); - } - - void EndPath(const GRState* St) { - ConstraintMgr->EndPath(St); - } -}; - - -//===----------------------------------------------------------------------===// -// 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); -} - -inline const GRState *GRState::Assume(DefinedOrUnknownSVal Cond, - bool Assumption) const { - if (Cond.isUnknown()) - return this; - - return getStateManager().ConstraintMgr->Assume(this, cast<DefinedSVal>(Cond), - Assumption); -} - -inline std::pair<const GRState*, const GRState*> -GRState::Assume(DefinedOrUnknownSVal Cond) const { - if (Cond.isUnknown()) - return std::make_pair(this, this); - - return getStateManager().ConstraintMgr->AssumeDual(this, - cast<DefinedSVal>(Cond)); -} - -inline const GRState *GRState::bindLoc(SVal LV, SVal V) const { - return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V); -} - -inline Loc GRState::getLValue(const VarDecl* VD, - const LocationContext *LC) const { - return getStateManager().StoreMgr->getLValueVar(VD, LC); -} - -inline Loc GRState::getLValue(const StringLiteral *literal) const { - return getStateManager().StoreMgr->getLValueString(literal); -} - -inline Loc GRState::getLValue(const CompoundLiteralExpr *literal, - const LocationContext *LC) const { - return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC); -} - -inline SVal GRState::getLValue(const ObjCIvarDecl *D, SVal Base) const { - return getStateManager().StoreMgr->getLValueIvar(D, Base); -} - -inline SVal GRState::getLValue(const FieldDecl* D, SVal Base) const { - return getStateManager().StoreMgr->getLValueField(D, Base); -} - -inline SVal GRState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{ - return getStateManager().StoreMgr->getLValueElement(ElementType, Idx, Base); -} - -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().ValueMgr); -} - -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()) - return getSVal(S); - } - - return UnknownVal(); -} - -inline SVal GRState::getSVal(Loc LV, QualType T) const { - return getStateManager().StoreMgr->Retrieve(St, LV, T); -} - -inline SVal GRState::getSVal(const MemRegion* R) const { - return getStateManager().StoreMgr->Retrieve(St, loc::MemRegionVal(R)); -} - -inline BasicValueFactory &GRState::getBasicVals() const { - return getStateManager().getBasicVals(); -} - -inline SymbolManager &GRState::getSymbolManager() const { - return getStateManager().getSymbolManager(); -} - -template<typename T> -const GRState *GRState::add(typename GRStateTrait<T>::key_type K) const { - return getStateManager().add<T>(this, K, get_context<T>()); -} - -template <typename T> -typename GRStateTrait<T>::context_type GRState::get_context() const { - return getStateManager().get_context<T>(); -} - -template<typename T> -const GRState *GRState::remove(typename GRStateTrait<T>::key_type K) const { - return getStateManager().remove<T>(this, K, get_context<T>()); -} - -template<typename T> -const GRState *GRState::remove(typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::context_type C) const { - return getStateManager().remove<T>(this, K, C); -} - -template <typename T> -const GRState *GRState::remove() const { - return getStateManager().remove<T>(this); -} - -template<typename T> -const GRState *GRState::set(typename GRStateTrait<T>::data_type D) const { - return getStateManager().set<T>(this, D); -} - -template<typename T> -const GRState *GRState::set(typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::value_type E) const { - return getStateManager().set<T>(this, K, E, get_context<T>()); -} - -template<typename T> -const GRState *GRState::set(typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::value_type E, - typename GRStateTrait<T>::context_type C) const { - return getStateManager().set<T>(this, K, E, C); -} - -template <typename CB> -CB GRState::scanReachableSymbols(SVal val) const { - CB cb(this); - scanReachableSymbols(val, cb); - return cb; -} - -template <typename CB> -CB GRState::scanReachableSymbols(const SVal *beg, const SVal *end) const { - CB cb(this); - scanReachableSymbols(beg, end, cb); - return cb; -} - -template <typename CB> -CB GRState::scanReachableSymbols(const MemRegion * const *beg, - const MemRegion * const *end) const { - CB cb(this); - scanReachableSymbols(beg, end, cb); - return cb; -} -} // end clang namespace - -#endif diff --git a/include/clang/Checker/PathSensitive/GRStateTrait.h b/include/clang/Checker/PathSensitive/GRStateTrait.h deleted file mode 100644 index 5189a1f..0000000 --- a/include/clang/Checker/PathSensitive/GRStateTrait.h +++ /dev/null @@ -1,148 +0,0 @@ -//==- GRStateTrait.h - Partial implementations of GRStateTrait -----*- 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 partial implementations of template specializations of -// the class GRStateTrait<>. GRStateTrait<> is used by GRState to implement -// set/get methods for mapulating a GRState's generic data map. -// -//===----------------------------------------------------------------------===// - - -#ifndef LLVM_CLANG_ANALYSIS_GRSTATETRAIT_H -#define LLVM_CLANG_ANALYSIS_GRSTATETRAIT_H - -namespace llvm { - class BumpPtrAllocator; - template <typename K, typename D, typename I> class ImmutableMap; - template <typename K, typename I> class ImmutableSet; - template <typename T> class ImmutableList; - template <typename T> class ImmutableListImpl; -} - -namespace clang { - template <typename T> struct GRStatePartialTrait; - - // Partial-specialization for ImmutableMap. - - template <typename Key, typename Data, typename Info> - struct GRStatePartialTrait< llvm::ImmutableMap<Key,Data,Info> > { - typedef llvm::ImmutableMap<Key,Data,Info> data_type; - typedef typename data_type::Factory& context_type; - typedef Key key_type; - typedef Data value_type; - typedef const value_type* lookup_type; - - static inline data_type MakeData(void* const* p) { - return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0); - } - static inline void* MakeVoidPtr(data_type B) { - return B.getRoot(); - } - static lookup_type Lookup(data_type B, key_type K) { - return B.lookup(K); - } - static data_type Set(data_type B, key_type K, value_type E,context_type F){ - return F.Add(B, K, E); - } - - static data_type Remove(data_type B, key_type K, context_type F) { - return F.Remove(B, K); - } - - static inline context_type MakeContext(void* p) { - return *((typename data_type::Factory*) p); - } - - static void* CreateContext(llvm::BumpPtrAllocator& Alloc) { - return new typename data_type::Factory(Alloc); - } - - static void DeleteContext(void* Ctx) { - delete (typename data_type::Factory*) Ctx; - } - }; - - - // Partial-specialization for ImmutableSet. - - template <typename Key, typename Info> - struct GRStatePartialTrait< llvm::ImmutableSet<Key,Info> > { - typedef llvm::ImmutableSet<Key,Info> data_type; - typedef typename data_type::Factory& context_type; - typedef Key key_type; - - static inline data_type MakeData(void* const* p) { - return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0); - } - - static inline void* MakeVoidPtr(data_type B) { - return B.getRoot(); - } - - static data_type Add(data_type B, key_type K, context_type F) { - return F.Add(B, K); - } - - static data_type Remove(data_type B, key_type K, context_type F) { - return F.Remove(B, K); - } - - static bool Contains(data_type B, key_type K) { - return B.contains(K); - } - - static inline context_type MakeContext(void* p) { - return *((typename data_type::Factory*) p); - } - - static void* CreateContext(llvm::BumpPtrAllocator& Alloc) { - return new typename data_type::Factory(Alloc); - } - - static void DeleteContext(void* Ctx) { - delete (typename data_type::Factory*) Ctx; - } - }; - - // Partial-specialization for ImmutableList. - - template <typename T> - struct GRStatePartialTrait< llvm::ImmutableList<T> > { - typedef llvm::ImmutableList<T> data_type; - typedef T key_type; - typedef typename data_type::Factory& context_type; - - static data_type Add(data_type L, key_type K, context_type F) { - return F.Add(K, L); - } - - static inline data_type MakeData(void* const* p) { - return p ? data_type((const llvm::ImmutableListImpl<T>*) *p) - : data_type(0); - } - - static inline void* MakeVoidPtr(data_type D) { - return (void*) D.getInternalPointer(); - } - - static inline context_type MakeContext(void* p) { - return *((typename data_type::Factory*) p); - } - - static void* CreateContext(llvm::BumpPtrAllocator& Alloc) { - return new typename data_type::Factory(Alloc); - } - - static void DeleteContext(void* Ctx) { - delete (typename data_type::Factory*) Ctx; - } - }; -} // end clang namespace - -#endif diff --git a/include/clang/Checker/PathSensitive/GRSubEngine.h b/include/clang/Checker/PathSensitive/GRSubEngine.h deleted file mode 100644 index 1904835..0000000 --- a/include/clang/Checker/PathSensitive/GRSubEngine.h +++ /dev/null @@ -1,107 +0,0 @@ -//== GRSubEngine.h - Interface of the subengine of GRCoreEngine ----*- C++ -*-// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the interface of a subengine of the GRCoreEngine. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_ANALYSIS_GRSUBENGINE_H -#define LLVM_CLANG_ANALYSIS_GRSUBENGINE_H - -#include "clang/Checker/PathSensitive/SVals.h" - -namespace clang { - -class AnalysisManager; -class CFGBlock; -class CFGElement; -class ExplodedNode; -class GRState; -class GRStateManager; -class GRBlockCounter; -class GRStmtNodeBuilder; -class GRBranchNodeBuilder; -class GRIndirectGotoNodeBuilder; -class GRSwitchNodeBuilder; -class GREndPathNodeBuilder; -class GRCallEnterNodeBuilder; -class GRCallExitNodeBuilder; -class LocationContext; -class MemRegion; -class Stmt; - -class GRSubEngine { -public: - virtual ~GRSubEngine() {} - - virtual const GRState* getInitialState(const LocationContext *InitLoc) = 0; - - virtual AnalysisManager &getAnalysisManager() = 0; - - virtual GRStateManager &getStateManager() = 0; - - /// Called by GRCoreEngine. Used to generate new successor - /// nodes by processing the 'effects' of a block-level statement. - virtual void ProcessStmt(const CFGElement E, GRStmtNodeBuilder& builder) = 0; - - /// Called by GRCoreEngine when start processing - /// a CFGBlock. This method returns true if the analysis should continue - /// exploring the given path, and false otherwise. - virtual bool ProcessBlockEntrance(const CFGBlock* B, const ExplodedNode *Pred, - GRBlockCounter BC) = 0; - - /// Called by GRCoreEngine. Used to generate successor - /// nodes by processing the 'effects' of a branch condition. - virtual void ProcessBranch(const Stmt* Condition, const Stmt* Term, - GRBranchNodeBuilder& builder) = 0; - - /// Called by GRCoreEngine. Used to generate successor - /// nodes by processing the 'effects' of a computed goto jump. - virtual void ProcessIndirectGoto(GRIndirectGotoNodeBuilder& builder) = 0; - - /// Called by GRCoreEngine. Used to generate successor - /// nodes by processing the 'effects' of a switch statement. - virtual void ProcessSwitch(GRSwitchNodeBuilder& builder) = 0; - - /// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path - /// nodes when the control reaches the end of a function. - virtual void ProcessEndPath(GREndPathNodeBuilder& builder) = 0; - - // Generate the entry node of the callee. - virtual void ProcessCallEnter(GRCallEnterNodeBuilder &builder) = 0; - - // Generate the first post callsite node. - virtual void ProcessCallExit(GRCallExitNodeBuilder &builder) = 0; - - /// Called by ConstraintManager. Used to call checker-specific - /// logic for handling assumptions on symbolic values. - virtual const GRState* ProcessAssume(const GRState *state, - SVal cond, bool assumption) = 0; - - /// WantsRegionChangeUpdate - Called by GRStateManager to determine if a - /// region change should trigger a ProcessRegionChanges update. - virtual bool WantsRegionChangeUpdate(const GRState* state) = 0; - - /// ProcessRegionChanges - Called by GRStateManager whenever a change is made - /// to the store. Used to update checkers that track region values. - virtual const GRState* ProcessRegionChanges(const GRState* state, - const MemRegion* const *Begin, - const MemRegion* const *End) = 0; - - inline const GRState* ProcessRegionChange(const GRState* state, - const MemRegion* MR) { - return ProcessRegionChanges(state, &MR, &MR+1); - } - - /// Called by GRCoreEngine when the analysis worklist is either empty or the - // maximum number of analysis steps have been reached. - virtual void ProcessEndWorklist(bool hasWorkRemaining) = 0; -}; -} - -#endif diff --git a/include/clang/Checker/PathSensitive/GRTransferFuncs.h b/include/clang/Checker/PathSensitive/GRTransferFuncs.h deleted file mode 100644 index 320b7f7..0000000 --- a/include/clang/Checker/PathSensitive/GRTransferFuncs.h +++ /dev/null @@ -1,87 +0,0 @@ -//== GRTransferFuncs.h - Path-Sens. Transfer Functions Interface -*- 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 GRTransferFuncs, which provides a base-class that -// defines an interface for transfer functions used by GRExprEngine. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_GRTF -#define LLVM_CLANG_ANALYSIS_GRTF - -#include "clang/Checker/PathSensitive/GRState.h" -#include "clang/Checker/PathSensitive/SVals.h" -#include <vector> - -namespace clang { -class ExplodedNode; -class ExplodedNodeSet; -class GREndPathNodeBuilder; -class GRExprEngine; -class GRStmtNodeBuilder; -class GRStmtNodeBuilderRef; -class ObjCMessageExpr; - -class GRTransferFuncs { -public: - GRTransferFuncs() {} - virtual ~GRTransferFuncs() {} - - virtual void RegisterPrinters(std::vector<GRState::Printer*>& Printers) {} - virtual void RegisterChecks(GRExprEngine& Eng) {} - - - // Calls. - - virtual void EvalCall(ExplodedNodeSet& Dst, - GRExprEngine& Engine, - GRStmtNodeBuilder& Builder, - const CallExpr* CE, SVal L, - ExplodedNode* Pred) {} - - virtual void EvalObjCMessageExpr(ExplodedNodeSet& Dst, - GRExprEngine& Engine, - GRStmtNodeBuilder& Builder, - const ObjCMessageExpr* ME, - ExplodedNode* Pred, - const GRState *state) {} - - // Stores. - - virtual void EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) {} - - // End-of-path and dead symbol notification. - - virtual void EvalEndPath(GRExprEngine& Engine, - GREndPathNodeBuilder& Builder) {} - - - virtual void EvalDeadSymbols(ExplodedNodeSet& Dst, - GRExprEngine& Engine, - GRStmtNodeBuilder& Builder, - ExplodedNode* Pred, - const GRState* state, - SymbolReaper& SymReaper) {} - - // Return statements. - virtual void EvalReturn(ExplodedNodeSet& Dst, - GRExprEngine& Engine, - GRStmtNodeBuilder& Builder, - const ReturnStmt* S, - ExplodedNode* Pred) {} - - // Assumptions. - virtual const GRState* EvalAssume(const GRState *state, - SVal Cond, bool Assumption) { - return state; - } -}; -} // end clang namespace - -#endif diff --git a/include/clang/Checker/PathSensitive/GRWorkList.h b/include/clang/Checker/PathSensitive/GRWorkList.h deleted file mode 100644 index 315b614..0000000 --- a/include/clang/Checker/PathSensitive/GRWorkList.h +++ /dev/null @@ -1,79 +0,0 @@ -//==- GRWorkList.h - Worklist class used by GRCoreEngine -----------*- 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 GRWorkList, a pure virtual class that represents an opaque -// worklist used by GRCoreEngine to explore the reachability state space. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_GRWORKLIST -#define LLVM_CLANG_ANALYSIS_GRWORKLIST - -#include "clang/Checker/PathSensitive/GRBlockCounter.h" -#include <cstddef> - -namespace clang { - -class CFGBlock; -class ExplodedNode; -class ExplodedNodeImpl; - -class GRWorkListUnit { - ExplodedNode* Node; - GRBlockCounter Counter; - const CFGBlock* Block; - unsigned BlockIdx; // This is the index of the next statement. - -public: - GRWorkListUnit(ExplodedNode* N, GRBlockCounter C, - const CFGBlock* B, unsigned idx) - : Node(N), - Counter(C), - Block(B), - BlockIdx(idx) {} - - explicit GRWorkListUnit(ExplodedNode* N, GRBlockCounter C) - : Node(N), - Counter(C), - Block(NULL), - BlockIdx(0) {} - - ExplodedNode* getNode() const { return Node; } - GRBlockCounter getBlockCounter() const { return Counter; } - const CFGBlock* getBlock() const { return Block; } - unsigned getIndex() const { return BlockIdx; } -}; - -class GRWorkList { - GRBlockCounter CurrentCounter; -public: - virtual ~GRWorkList(); - virtual bool hasWork() const = 0; - - virtual void Enqueue(const GRWorkListUnit& U) = 0; - - void Enqueue(ExplodedNode* N, const CFGBlock* B, unsigned idx) { - Enqueue(GRWorkListUnit(N, CurrentCounter, B, idx)); - } - - void Enqueue(ExplodedNode* N) { - Enqueue(GRWorkListUnit(N, CurrentCounter)); - } - - virtual GRWorkListUnit Dequeue() = 0; - - void setBlockCounter(GRBlockCounter C) { CurrentCounter = C; } - GRBlockCounter getBlockCounter() const { return CurrentCounter; } - - static GRWorkList *MakeDFS(); - static GRWorkList *MakeBFS(); - static GRWorkList *MakeBFSBlockDFSContents(); -}; -} // end clang namespace -#endif diff --git a/include/clang/Checker/PathSensitive/MemRegion.h b/include/clang/Checker/PathSensitive/MemRegion.h deleted file mode 100644 index 96f906a..0000000 --- a/include/clang/Checker/PathSensitive/MemRegion.h +++ /dev/null @@ -1,1041 +0,0 @@ -//== MemRegion.h - Abstract memory regions for static analysis --*- C++ -*--==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines MemRegion and its subclasses. MemRegion defines a -// partially-typed abstraction of memory useful for path-sensitive dataflow -// analyses. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_MEMREGION_H -#define LLVM_CLANG_ANALYSIS_MEMREGION_H - -#include "clang/AST/Decl.h" -#include "clang/AST/DeclObjC.h" -#include "clang/Checker/PathSensitive/SVals.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/ADT/FoldingSet.h" -#include <string> - -namespace llvm { -class BumpPtrAllocator; -class raw_ostream; -} - -namespace clang { - -class MemRegionManager; -class MemSpaceRegion; -class LocationContext; -class StackFrameContext; -class ValueManager; -class VarRegion; -class CodeTextRegion; - -/// Represent a region's offset within the top level base region. -class RegionOffset { - /// The base region. - const MemRegion *R; - - /// The bit offset within the base region. It shouldn't be negative. - int64_t Offset; - -public: - RegionOffset(const MemRegion *r) : R(r), Offset(0) {} - RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {} - - const MemRegion *getRegion() const { return R; } - int64_t getOffset() const { return Offset; } -}; - -//===----------------------------------------------------------------------===// -// Base region classes. -//===----------------------------------------------------------------------===// - -/// MemRegion - The root abstract class for all memory regions. -class MemRegion : public llvm::FoldingSetNode { - friend class MemRegionManager; -public: - enum Kind { - // Memory spaces. - GenericMemSpaceRegionKind, - StackLocalsSpaceRegionKind, - StackArgumentsSpaceRegionKind, - HeapSpaceRegionKind, - UnknownSpaceRegionKind, - NonStaticGlobalSpaceRegionKind, - StaticGlobalSpaceRegionKind, - BEG_GLOBAL_MEMSPACES = NonStaticGlobalSpaceRegionKind, - END_GLOBAL_MEMSPACES = StaticGlobalSpaceRegionKind, - BEG_MEMSPACES = GenericMemSpaceRegionKind, - END_MEMSPACES = StaticGlobalSpaceRegionKind, - // Untyped regions. - SymbolicRegionKind, - AllocaRegionKind, - // Typed regions. - BEG_TYPED_REGIONS, - FunctionTextRegionKind = BEG_TYPED_REGIONS, - BlockTextRegionKind, - BlockDataRegionKind, - CompoundLiteralRegionKind, - CXXThisRegionKind, - StringRegionKind, - ElementRegionKind, - // Decl Regions. - BEG_DECL_REGIONS, - VarRegionKind = BEG_DECL_REGIONS, - FieldRegionKind, - ObjCIvarRegionKind, - CXXObjectRegionKind, - END_DECL_REGIONS = CXXObjectRegionKind, - END_TYPED_REGIONS = END_DECL_REGIONS - }; - -private: - const Kind kind; - -protected: - MemRegion(Kind k) : kind(k) {} - virtual ~MemRegion(); - -public: - ASTContext &getContext() const; - - virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0; - - virtual MemRegionManager* getMemRegionManager() const = 0; - - std::string getString() const; - - const MemSpaceRegion *getMemorySpace() const; - - const MemRegion *getBaseRegion() const; - - const MemRegion *StripCasts() const; - - bool hasGlobalsOrParametersStorage() const; - - bool hasStackStorage() const; - - bool hasStackNonParametersStorage() const; - - bool hasStackParametersStorage() const; - - /// Compute the offset within the top level memory object. - RegionOffset getAsOffset() const; - - virtual void dumpToStream(llvm::raw_ostream& os) const; - - void dump() const; - - Kind getKind() const { return kind; } - - template<typename RegionTy> const RegionTy* getAs() const; - - virtual bool isBoundable() const { return false; } - - static bool classof(const MemRegion*) { return true; } -}; - -/// MemSpaceRegion - A memory region that represents and "memory space"; -/// for example, the set of global variables, the stack frame, etc. -class MemSpaceRegion : public MemRegion { -protected: - friend class MemRegionManager; - - MemRegionManager *Mgr; - - MemSpaceRegion(MemRegionManager *mgr, Kind k = GenericMemSpaceRegionKind) - : MemRegion(k), Mgr(mgr) { - assert(classof(this)); - } - - MemRegionManager* getMemRegionManager() const { return Mgr; } - -public: - bool isBoundable() const { return false; } - - void Profile(llvm::FoldingSetNodeID &ID) const; - - static bool classof(const MemRegion *R) { - Kind k = R->getKind(); - return k >= BEG_MEMSPACES && k <= END_MEMSPACES; - } -}; - -class GlobalsSpaceRegion : public MemSpaceRegion { -protected: - GlobalsSpaceRegion(MemRegionManager *mgr, Kind k) - : MemSpaceRegion(mgr, k) {} -public: - static bool classof(const MemRegion *R) { - Kind k = R->getKind(); - return k >= BEG_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES; - } -}; - -class StaticGlobalSpaceRegion : public GlobalsSpaceRegion { - friend class MemRegionManager; - - const CodeTextRegion *CR; - - StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr) - : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {} - -public: - void Profile(llvm::FoldingSetNodeID &ID) const; - - void dumpToStream(llvm::raw_ostream& os) const; - - const CodeTextRegion *getCodeRegion() const { return CR; } - - static bool classof(const MemRegion *R) { - return R->getKind() == StaticGlobalSpaceRegionKind; - } -}; - -class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion { - friend class MemRegionManager; - - NonStaticGlobalSpaceRegion(MemRegionManager *mgr) - : GlobalsSpaceRegion(mgr, NonStaticGlobalSpaceRegionKind) {} - -public: - - void dumpToStream(llvm::raw_ostream& os) const; - - static bool classof(const MemRegion *R) { - return R->getKind() == NonStaticGlobalSpaceRegionKind; - } -}; - -class HeapSpaceRegion : public MemSpaceRegion { - friend class MemRegionManager; - - HeapSpaceRegion(MemRegionManager *mgr) - : MemSpaceRegion(mgr, HeapSpaceRegionKind) {} -public: - static bool classof(const MemRegion *R) { - return R->getKind() == HeapSpaceRegionKind; - } -}; - -class UnknownSpaceRegion : public MemSpaceRegion { - friend class MemRegionManager; - UnknownSpaceRegion(MemRegionManager *mgr) - : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {} -public: - static bool classof(const MemRegion *R) { - return R->getKind() == UnknownSpaceRegionKind; - } -}; - -class StackSpaceRegion : public MemSpaceRegion { -private: - const StackFrameContext *SFC; - -protected: - StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc) - : MemSpaceRegion(mgr, k), SFC(sfc) { - assert(classof(this)); - } - -public: - const StackFrameContext *getStackFrame() const { return SFC; } - - void Profile(llvm::FoldingSetNodeID &ID) const; - - static bool classof(const MemRegion *R) { - Kind k = R->getKind(); - return k >= StackLocalsSpaceRegionKind && - k <= StackArgumentsSpaceRegionKind; - } -}; - -class StackLocalsSpaceRegion : public StackSpaceRegion { -private: - friend class MemRegionManager; - StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc) - : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {} -public: - static bool classof(const MemRegion *R) { - return R->getKind() == StackLocalsSpaceRegionKind; - } -}; - -class StackArgumentsSpaceRegion : public StackSpaceRegion { -private: - friend class MemRegionManager; - StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc) - : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {} -public: - static bool classof(const MemRegion *R) { - return R->getKind() == StackArgumentsSpaceRegionKind; - } -}; - - -/// SubRegion - A region that subsets another larger region. Most regions -/// are subclasses of SubRegion. -class SubRegion : public MemRegion { -protected: - const MemRegion* superRegion; - SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {} -public: - const MemRegion* getSuperRegion() const { - return superRegion; - } - - /// getExtent - Returns the size of the region in bytes. - virtual DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const { - return UnknownVal(); - } - - MemRegionManager* getMemRegionManager() const; - - bool isSubRegionOf(const MemRegion* R) const; - - static bool classof(const MemRegion* R) { - return R->getKind() > END_MEMSPACES; - } -}; - -//===----------------------------------------------------------------------===// -// MemRegion subclasses. -//===----------------------------------------------------------------------===// - -/// AllocaRegion - A region that represents an untyped blob of bytes created -/// by a call to 'alloca'. -class AllocaRegion : public SubRegion { - friend class MemRegionManager; -protected: - unsigned Cnt; // Block counter. Used to distinguish different pieces of - // memory allocated by alloca at the same call site. - const Expr* Ex; - - AllocaRegion(const Expr* ex, unsigned cnt, const MemRegion *superRegion) - : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {} - -public: - - const Expr* getExpr() const { return Ex; } - - bool isBoundable() const { return true; } - - DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const; - - void Profile(llvm::FoldingSetNodeID& ID) const; - - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr* Ex, - unsigned Cnt, const MemRegion *superRegion); - - void dumpToStream(llvm::raw_ostream& os) const; - - static bool classof(const MemRegion* R) { - return R->getKind() == AllocaRegionKind; - } -}; - -/// TypedRegion - An abstract class representing regions that are typed. -class TypedRegion : public SubRegion { -protected: - TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {} - -public: - virtual QualType getValueType() const = 0; - - virtual QualType getLocationType() const { - // FIXME: We can possibly optimize this later to cache this value. - return getContext().getPointerType(getValueType()); - } - - QualType getDesugaredValueType() const { - QualType T = getValueType(); - return T.getTypePtr() ? T.getDesugaredType() : T; - } - - QualType getDesugaredLocationType() const { - return getLocationType().getDesugaredType(); - } - - bool isBoundable() const { return true; } - - static bool classof(const MemRegion* R) { - unsigned k = R->getKind(); - return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS; - } -}; - - -class CodeTextRegion : public TypedRegion { -protected: - CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {} -public: - QualType getValueType() const { - assert(0 && "Do not get the object type of a CodeTextRegion."); - return QualType(); - } - - bool isBoundable() const { return false; } - - static bool classof(const MemRegion* R) { - Kind k = R->getKind(); - return k >= FunctionTextRegionKind && k <= BlockTextRegionKind; - } -}; - -/// FunctionTextRegion - A region that represents code texts of function. -class FunctionTextRegion : public CodeTextRegion { - const FunctionDecl *FD; -public: - FunctionTextRegion(const FunctionDecl* fd, const MemRegion* sreg) - : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {} - - QualType getLocationType() const { - return getContext().getPointerType(FD->getType()); - } - - const FunctionDecl *getDecl() const { - return FD; - } - - virtual void dumpToStream(llvm::raw_ostream& os) const; - - void Profile(llvm::FoldingSetNodeID& ID) const; - - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FunctionDecl *FD, - const MemRegion*); - - static bool classof(const MemRegion* R) { - return R->getKind() == FunctionTextRegionKind; - } -}; - - -/// BlockTextRegion - A region that represents code texts of blocks (closures). -/// Blocks are represented with two kinds of regions. BlockTextRegions -/// represent the "code", while BlockDataRegions represent instances of blocks, -/// which correspond to "code+data". The distinction is important, because -/// like a closure a block captures the values of externally referenced -/// variables. -class BlockTextRegion : public CodeTextRegion { - friend class MemRegionManager; - - const BlockDecl *BD; - AnalysisContext *AC; - CanQualType locTy; - - BlockTextRegion(const BlockDecl *bd, CanQualType lTy, - AnalysisContext *ac, const MemRegion* sreg) - : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {} - -public: - QualType getLocationType() const { - return locTy; - } - - const BlockDecl *getDecl() const { - return BD; - } - - AnalysisContext *getAnalysisContext() const { return AC; } - - virtual void dumpToStream(llvm::raw_ostream& os) const; - - void Profile(llvm::FoldingSetNodeID& ID) const; - - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD, - CanQualType, const AnalysisContext*, - const MemRegion*); - - static bool classof(const MemRegion* R) { - return R->getKind() == BlockTextRegionKind; - } -}; - -/// BlockDataRegion - A region that represents a block instance. -/// Blocks are represented with two kinds of regions. BlockTextRegions -/// represent the "code", while BlockDataRegions represent instances of blocks, -/// which correspond to "code+data". The distinction is important, because -/// like a closure a block captures the values of externally referenced -/// variables. -class BlockDataRegion : public SubRegion { - friend class MemRegionManager; - const BlockTextRegion *BC; - const LocationContext *LC; // Can be null */ - void *ReferencedVars; - - BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc, - const MemRegion *sreg) - : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), ReferencedVars(0) {} - -public: - const BlockTextRegion *getCodeRegion() const { return BC; } - - const BlockDecl *getDecl() const { return BC->getDecl(); } - - class referenced_vars_iterator { - const MemRegion * const *R; - public: - explicit referenced_vars_iterator(const MemRegion * const *r) : R(r) {} - - operator const MemRegion * const *() const { - return R; - } - - const VarRegion* operator*() const { - return cast<VarRegion>(*R); - } - - bool operator==(const referenced_vars_iterator &I) const { - return I.R == R; - } - bool operator!=(const referenced_vars_iterator &I) const { - return I.R != R; - } - referenced_vars_iterator& operator++() { - ++R; - return *this; - } - }; - - referenced_vars_iterator referenced_vars_begin() const; - referenced_vars_iterator referenced_vars_end() const; - - virtual void dumpToStream(llvm::raw_ostream& os) const; - - void Profile(llvm::FoldingSetNodeID& ID) const; - - static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *, - const LocationContext *, const MemRegion *); - - static bool classof(const MemRegion* R) { - return R->getKind() == BlockDataRegionKind; - } -private: - void LazyInitializeReferencedVars(); -}; - -/// SymbolicRegion - A special, "non-concrete" region. Unlike other region -/// clases, SymbolicRegion represents a region that serves as an alias for -/// either a real region, a NULL pointer, etc. It essentially is used to -/// map the concept of symbolic values into the domain of regions. Symbolic -/// regions do not need to be typed. -class SymbolicRegion : public SubRegion { -protected: - const SymbolRef sym; - -public: - SymbolicRegion(const SymbolRef s, const MemRegion* sreg) - : SubRegion(sreg, SymbolicRegionKind), sym(s) {} - - SymbolRef getSymbol() const { - return sym; - } - - bool isBoundable() const { return true; } - - DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const; - - void Profile(llvm::FoldingSetNodeID& ID) const; - - static void ProfileRegion(llvm::FoldingSetNodeID& ID, - SymbolRef sym, - const MemRegion* superRegion); - - void dumpToStream(llvm::raw_ostream& os) const; - - static bool classof(const MemRegion* R) { - return R->getKind() == SymbolicRegionKind; - } -}; - -/// StringRegion - Region associated with a StringLiteral. -class StringRegion : public TypedRegion { - friend class MemRegionManager; - const StringLiteral* Str; -protected: - - StringRegion(const StringLiteral* str, const MemRegion* sreg) - : TypedRegion(sreg, StringRegionKind), Str(str) {} - - static void ProfileRegion(llvm::FoldingSetNodeID& ID, - const StringLiteral* Str, - const MemRegion* superRegion); - -public: - - const StringLiteral* getStringLiteral() const { return Str; } - - QualType getValueType() const { - return Str->getType(); - } - - DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const; - - bool isBoundable() const { return false; } - - void Profile(llvm::FoldingSetNodeID& ID) const { - ProfileRegion(ID, Str, superRegion); - } - - void dumpToStream(llvm::raw_ostream& os) const; - - static bool classof(const MemRegion* R) { - return R->getKind() == StringRegionKind; - } -}; - -/// CompoundLiteralRegion - A memory region representing a compound literal. -/// Compound literals are essentially temporaries that are stack allocated -/// or in the global constant pool. -class CompoundLiteralRegion : public TypedRegion { -private: - friend class MemRegionManager; - const CompoundLiteralExpr* CL; - - CompoundLiteralRegion(const CompoundLiteralExpr* cl, const MemRegion* sReg) - : TypedRegion(sReg, CompoundLiteralRegionKind), CL(cl) {} - - static void ProfileRegion(llvm::FoldingSetNodeID& ID, - const CompoundLiteralExpr* CL, - const MemRegion* superRegion); -public: - QualType getValueType() const { - return CL->getType(); - } - - bool isBoundable() const { return !CL->isFileScope(); } - - void Profile(llvm::FoldingSetNodeID& ID) const; - - void dumpToStream(llvm::raw_ostream& os) const; - - const CompoundLiteralExpr* getLiteralExpr() const { return CL; } - - static bool classof(const MemRegion* R) { - return R->getKind() == CompoundLiteralRegionKind; - } -}; - -class DeclRegion : public TypedRegion { -protected: - const Decl* D; - - DeclRegion(const Decl* d, const MemRegion* sReg, Kind k) - : TypedRegion(sReg, k), D(d) {} - - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D, - const MemRegion* superRegion, Kind k); - -public: - const Decl* getDecl() const { return D; } - void Profile(llvm::FoldingSetNodeID& ID) const; - - DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const; - - static bool classof(const MemRegion* R) { - unsigned k = R->getKind(); - return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS; - } -}; - -class VarRegion : public DeclRegion { - friend class MemRegionManager; - - // Constructors and private methods. - VarRegion(const VarDecl* vd, const MemRegion* sReg) - : DeclRegion(vd, sReg, VarRegionKind) {} - - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl* VD, - const MemRegion *superRegion) { - DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind); - } - - void Profile(llvm::FoldingSetNodeID& ID) const; - -public: - const VarDecl *getDecl() const { return cast<VarDecl>(D); } - - const StackFrameContext *getStackFrame() const; - - QualType getValueType() const { - // FIXME: We can cache this if needed. - return getDecl()->getType(); - } - - void dumpToStream(llvm::raw_ostream& os) const; - - static bool classof(const MemRegion* R) { - return R->getKind() == VarRegionKind; - } -}; - -/// CXXThisRegion - Represents the region for the implicit 'this' parameter -/// in a call to a C++ method. This region doesn't represent the object -/// referred to by 'this', but rather 'this' itself. -class CXXThisRegion : public TypedRegion { - friend class MemRegionManager; - CXXThisRegion(const PointerType *thisPointerTy, - const MemRegion *sReg) - : TypedRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {} - - static void ProfileRegion(llvm::FoldingSetNodeID &ID, - const PointerType *PT, - const MemRegion *sReg); - - void Profile(llvm::FoldingSetNodeID &ID) const; - -public: - QualType getValueType() const { - return QualType(ThisPointerTy, 0); - } - - void dumpToStream(llvm::raw_ostream& os) const; - - static bool classof(const MemRegion* R) { - return R->getKind() == CXXThisRegionKind; - } - -private: - const PointerType *ThisPointerTy; -}; - -class FieldRegion : public DeclRegion { - friend class MemRegionManager; - - FieldRegion(const FieldDecl* fd, const MemRegion* sReg) - : DeclRegion(fd, sReg, FieldRegionKind) {} - -public: - - void dumpToStream(llvm::raw_ostream& os) const; - - const FieldDecl* getDecl() const { return cast<FieldDecl>(D); } - - QualType getValueType() const { - // FIXME: We can cache this if needed. - return getDecl()->getType(); - } - - DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const; - - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl* FD, - const MemRegion* superRegion) { - DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind); - } - - static bool classof(const MemRegion* R) { - return R->getKind() == FieldRegionKind; - } -}; - -class ObjCIvarRegion : public DeclRegion { - - friend class MemRegionManager; - - ObjCIvarRegion(const ObjCIvarDecl* ivd, const MemRegion* sReg) - : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {} - - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl* ivd, - const MemRegion* superRegion) { - DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind); - } - -public: - const ObjCIvarDecl* getDecl() const { return cast<ObjCIvarDecl>(D); } - QualType getValueType() const { return getDecl()->getType(); } - - void dumpToStream(llvm::raw_ostream& os) const; - - static bool classof(const MemRegion* R) { - return R->getKind() == ObjCIvarRegionKind; - } -}; -//===----------------------------------------------------------------------===// -// Auxillary data classes for use with MemRegions. -//===----------------------------------------------------------------------===// - -class ElementRegion; - -class RegionRawOffset { -private: - friend class ElementRegion; - - const MemRegion *Region; - int64_t Offset; - - RegionRawOffset(const MemRegion* reg, int64_t offset = 0) - : Region(reg), Offset(offset) {} - -public: - // FIXME: Eventually support symbolic offsets. - int64_t getByteOffset() const { return Offset; } - const MemRegion *getRegion() const { return Region; } - - void dumpToStream(llvm::raw_ostream& os) const; - void dump() const; -}; - -class ElementRegion : public TypedRegion { - friend class MemRegionManager; - - QualType ElementType; - SVal Index; - - ElementRegion(QualType elementType, SVal Idx, const MemRegion* sReg) - : TypedRegion(sReg, ElementRegionKind), - ElementType(elementType), Index(Idx) { - assert((!isa<nonloc::ConcreteInt>(&Idx) || - cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) && - "The index must be signed"); - } - - static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType, - SVal Idx, const MemRegion* superRegion); - -public: - - SVal getIndex() const { return Index; } - - QualType getValueType() const { - return ElementType; - } - - QualType getElementType() const { - return ElementType; - } - /// Compute the offset within the array. The array might also be a subobject. - RegionRawOffset getAsArrayOffset() const; - - void dumpToStream(llvm::raw_ostream& os) const; - - void Profile(llvm::FoldingSetNodeID& ID) const; - - static bool classof(const MemRegion* R) { - return R->getKind() == ElementRegionKind; - } -}; - -// C++ temporary object associated with an expression. -class CXXObjectRegion : public TypedRegion { - friend class MemRegionManager; - - Expr const *Ex; - - CXXObjectRegion(Expr const *E, MemRegion const *sReg) - : TypedRegion(sReg, CXXObjectRegionKind), Ex(E) {} - - static void ProfileRegion(llvm::FoldingSetNodeID &ID, - Expr const *E, const MemRegion *sReg); - -public: - QualType getValueType() const { - return Ex->getType(); - } - - void Profile(llvm::FoldingSetNodeID &ID) const; - - static bool classof(const MemRegion* R) { - return R->getKind() == CXXObjectRegionKind; - } -}; - -template<typename RegionTy> -const RegionTy* MemRegion::getAs() const { - if (const RegionTy* RT = dyn_cast<RegionTy>(this)) - return RT; - - return NULL; -} - -//===----------------------------------------------------------------------===// -// MemRegionManager - Factory object for creating regions. -//===----------------------------------------------------------------------===// - -class MemRegionManager { - ASTContext &C; - llvm::BumpPtrAllocator& A; - llvm::FoldingSet<MemRegion> Regions; - - NonStaticGlobalSpaceRegion *globals; - - llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *> - StackLocalsSpaceRegions; - llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *> - StackArgumentsSpaceRegions; - llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *> - StaticsGlobalSpaceRegions; - - HeapSpaceRegion *heap; - UnknownSpaceRegion *unknown; - MemSpaceRegion *code; - -public: - MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a) - : C(c), A(a), globals(0), heap(0), unknown(0), code(0) {} - - ~MemRegionManager(); - - ASTContext &getContext() { return C; } - - llvm::BumpPtrAllocator &getAllocator() { return A; } - - /// getStackLocalsRegion - Retrieve the memory region associated with the - /// specified stack frame. - const StackLocalsSpaceRegion * - getStackLocalsRegion(const StackFrameContext *STC); - - /// getStackArgumentsRegion - Retrieve the memory region associated with - /// function/method arguments of the specified stack frame. - const StackArgumentsSpaceRegion * - getStackArgumentsRegion(const StackFrameContext *STC); - - /// getGlobalsRegion - Retrieve the memory region associated with - /// global variables. - const GlobalsSpaceRegion *getGlobalsRegion(const CodeTextRegion *R = 0); - - /// getHeapRegion - Retrieve the memory region associated with the - /// generic "heap". - const HeapSpaceRegion *getHeapRegion(); - - /// getUnknownRegion - Retrieve the memory region associated with unknown - /// memory space. - const MemSpaceRegion *getUnknownRegion(); - - const MemSpaceRegion *getCodeRegion(); - - /// getAllocaRegion - Retrieve a region associated with a call to alloca(). - const AllocaRegion *getAllocaRegion(const Expr* Ex, unsigned Cnt, - const LocationContext *LC); - - /// getCompoundLiteralRegion - Retrieve the region associated with a - /// given CompoundLiteral. - const CompoundLiteralRegion* - getCompoundLiteralRegion(const CompoundLiteralExpr* CL, - const LocationContext *LC); - - /// getCXXThisRegion - Retrieve the [artifical] region associated with the - /// parameter 'this'. - const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy, - const LocationContext *LC); - - /// getSymbolicRegion - Retrieve or create a "symbolic" memory region. - const SymbolicRegion* getSymbolicRegion(SymbolRef sym); - - const StringRegion* getStringRegion(const StringLiteral* Str); - - /// getVarRegion - Retrieve or create the memory region associated with - /// a specified VarDecl and LocationContext. - const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC); - - /// getVarRegion - Retrieve or create the memory region associated with - /// a specified VarDecl and super region. - const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR); - - /// getElementRegion - Retrieve the memory region associated with the - /// associated element type, index, and super region. - const ElementRegion *getElementRegion(QualType elementType, SVal Idx, - const MemRegion *superRegion, - ASTContext &Ctx); - - const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER, - const MemRegion *superRegion) { - return getElementRegion(ER->getElementType(), ER->getIndex(), - superRegion, ER->getContext()); - } - - /// getFieldRegion - Retrieve or create the memory region associated with - /// a specified FieldDecl. 'superRegion' corresponds to the containing - /// memory region (which typically represents the memory representing - /// a structure or class). - const FieldRegion *getFieldRegion(const FieldDecl* fd, - const MemRegion* superRegion); - - const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR, - const MemRegion *superRegion) { - return getFieldRegion(FR->getDecl(), superRegion); - } - - /// getObjCIvarRegion - Retrieve or create the memory region associated with - /// a specified Objective-c instance variable. 'superRegion' corresponds - /// to the containing region (which typically represents the Objective-C - /// object). - const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl* ivd, - const MemRegion* superRegion); - - const CXXObjectRegion *getCXXObjectRegion(Expr const *Ex, - LocationContext const *LC); - - const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD); - const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD, - CanQualType locTy, - AnalysisContext *AC); - - /// getBlockDataRegion - Get the memory region associated with an instance - /// of a block. Unlike many other MemRegions, the LocationContext* - /// argument is allowed to be NULL for cases where we have no known - /// context. - const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc, - const LocationContext *lc = NULL); - - bool isGlobalsRegion(const MemRegion* R) { - assert(R); - return R == globals; - } - -private: - template <typename RegionTy, typename A1> - RegionTy* getRegion(const A1 a1); - - template <typename RegionTy, typename A1> - RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion); - - template <typename RegionTy, typename A1, typename A2> - RegionTy* getRegion(const A1 a1, const A2 a2); - - template <typename RegionTy, typename A1, typename A2> - RegionTy* getSubRegion(const A1 a1, const A2 a2, - const MemRegion* superRegion); - - template <typename RegionTy, typename A1, typename A2, typename A3> - RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3, - const MemRegion* superRegion); - - template <typename REG> - const REG* LazyAllocate(REG*& region); - - template <typename REG, typename ARG> - const REG* LazyAllocate(REG*& region, ARG a); -}; - -//===----------------------------------------------------------------------===// -// Out-of-line member definitions. -//===----------------------------------------------------------------------===// - -inline ASTContext& MemRegion::getContext() const { - return getMemRegionManager()->getContext(); -} - -} // end clang namespace - -//===----------------------------------------------------------------------===// -// Pretty-printing regions. -//===----------------------------------------------------------------------===// - -namespace llvm { -static inline raw_ostream& operator<<(raw_ostream& os, - const clang::MemRegion* R) { - R->dumpToStream(os); - return os; -} -} // end llvm namespace - -#endif diff --git a/include/clang/Checker/PathSensitive/SVals.h b/include/clang/Checker/PathSensitive/SVals.h deleted file mode 100644 index cdb338a..0000000 --- a/include/clang/Checker/PathSensitive/SVals.h +++ /dev/null @@ -1,503 +0,0 @@ -//== SVals.h - Abstract Values for Static Analysis ---------*- C++ -*--==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines SVal, Loc, and NonLoc, classes that represent -// abstract r-values for use with path-sensitive value tracking. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_RVALUE_H -#define LLVM_CLANG_ANALYSIS_RVALUE_H - -#include "clang/Checker/PathSensitive/SymbolManager.h" -#include "llvm/Support/Casting.h" -#include "llvm/ADT/ImmutableList.h" - -namespace llvm { - class raw_ostream; -} - -//==------------------------------------------------------------------------==// -// Base SVal types. -//==------------------------------------------------------------------------==// - -namespace clang { - -class CompoundValData; -class LazyCompoundValData; -class GRState; -class BasicValueFactory; -class MemRegion; -class TypedRegion; -class MemRegionManager; -class GRStateManager; -class ValueManager; - -class SVal { -public: - enum BaseKind { UndefinedKind, UnknownKind, LocKind, NonLocKind }; - enum { BaseBits = 2, BaseMask = 0x3 }; - -protected: - const void* Data; - unsigned Kind; - -protected: - SVal(const void* d, bool isLoc, unsigned ValKind) - : Data(d), Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {} - - explicit SVal(BaseKind k, const void* D = NULL) - : Data(D), Kind(k) {} - -public: - SVal() : Data(0), Kind(0) {} - ~SVal() {} - - /// BufferTy - A temporary buffer to hold a set of SVals. - typedef llvm::SmallVector<SVal,5> BufferTy; - - inline unsigned getRawKind() const { return Kind; } - inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); } - inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; } - - inline void Profile(llvm::FoldingSetNodeID& ID) const { - ID.AddInteger((unsigned) getRawKind()); - ID.AddPointer(Data); - } - - inline bool operator==(const SVal& R) const { - return getRawKind() == R.getRawKind() && Data == R.Data; - } - - inline bool operator!=(const SVal& R) const { - return !(*this == R); - } - - inline bool isUnknown() const { - return getRawKind() == UnknownKind; - } - - inline bool isUndef() const { - return getRawKind() == UndefinedKind; - } - - inline bool isUnknownOrUndef() const { - return getRawKind() <= UnknownKind; - } - - inline bool isValid() const { - return getRawKind() > UnknownKind; - } - - bool isConstant() const; - - bool isConstant(int I) const; - - bool isZeroConstant() const; - - /// hasConjuredSymbol - If this SVal wraps a conjured symbol, return true; - bool hasConjuredSymbol() const; - - /// getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a - /// CodeTextRegion wrapping a FunctionDecl, return that FunctionDecl. - /// Otherwise return 0. - const FunctionDecl* getAsFunctionDecl() const; - - /// getAsLocSymbol - If this SVal is a location (subclasses Loc) and - /// wraps a symbol, return that SymbolRef. Otherwise return NULL. - SymbolRef getAsLocSymbol() const; - - /// Get the symbol in the SVal or its base region. - SymbolRef getLocSymbolInBase() const; - - /// getAsSymbol - If this Sval wraps a symbol return that SymbolRef. - /// Otherwise return a SymbolRef where 'isValid()' returns false. - SymbolRef getAsSymbol() const; - - /// getAsSymbolicExpression - If this Sval wraps a symbolic expression then - /// return that expression. Otherwise return NULL. - const SymExpr *getAsSymbolicExpression() const; - - const MemRegion *getAsRegion() const; - - void dumpToStream(llvm::raw_ostream& OS) const; - void dump() const; - - // Iterators. - class symbol_iterator { - llvm::SmallVector<const SymExpr*, 5> itr; - void expand(); - public: - symbol_iterator() {} - symbol_iterator(const SymExpr* SE); - - symbol_iterator& operator++(); - SymbolRef operator*(); - - bool operator==(const symbol_iterator& X) const; - bool operator!=(const symbol_iterator& X) const; - }; - - symbol_iterator symbol_begin() const { - const SymExpr *SE = getAsSymbolicExpression(); - if (SE) - return symbol_iterator(SE); - else - return symbol_iterator(); - } - - symbol_iterator symbol_end() const { return symbol_iterator(); } - - // Implement isa<T> support. - static inline bool classof(const SVal*) { return true; } -}; - - -class UndefinedVal : public SVal { -public: - UndefinedVal() : SVal(UndefinedKind) {} - UndefinedVal(const void* D) : SVal(UndefinedKind, D) {} - - static inline bool classof(const SVal* V) { - return V->getBaseKind() == UndefinedKind; - } - - const void* getData() const { return Data; } -}; - -class DefinedOrUnknownSVal : public SVal { -private: - // Do not implement. We want calling these methods to be a compiler - // error since they are tautologically false. - bool isUndef() const; - bool isValid() const; - -protected: - explicit DefinedOrUnknownSVal(const void* d, bool isLoc, unsigned ValKind) - : SVal(d, isLoc, ValKind) {} - - explicit DefinedOrUnknownSVal(BaseKind k, void *D = NULL) - : SVal(k, D) {} - -public: - // Implement isa<T> support. - static inline bool classof(const SVal *V) { - return !V->isUndef(); - } -}; - -class UnknownVal : public DefinedOrUnknownSVal { -public: - UnknownVal() : DefinedOrUnknownSVal(UnknownKind) {} - - static inline bool classof(const SVal *V) { - return V->getBaseKind() == UnknownKind; - } -}; - -class DefinedSVal : public DefinedOrUnknownSVal { -private: - // Do not implement. We want calling these methods to be a compiler - // error since they are tautologically true/false. - bool isUnknown() const; - bool isUnknownOrUndef() const; - bool isValid() const; -protected: - DefinedSVal(const void* d, bool isLoc, unsigned ValKind) - : DefinedOrUnknownSVal(d, isLoc, ValKind) {} -public: - // Implement isa<T> support. - static inline bool classof(const SVal *V) { - return !V->isUnknownOrUndef(); - } -}; - -class NonLoc : public DefinedSVal { -protected: - NonLoc(unsigned SubKind, const void* d) : DefinedSVal(d, false, SubKind) {} - -public: - void dumpToStream(llvm::raw_ostream& Out) const; - - // Implement isa<T> support. - static inline bool classof(const SVal* V) { - return V->getBaseKind() == NonLocKind; - } -}; - -class Loc : public DefinedSVal { -protected: - Loc(unsigned SubKind, const void* D) - : DefinedSVal(const_cast<void*>(D), true, SubKind) {} - -public: - void dumpToStream(llvm::raw_ostream& Out) const; - - Loc(const Loc& X) : DefinedSVal(X.Data, true, X.getSubKind()) {} - Loc& operator=(const Loc& X) { memcpy(this, &X, sizeof(Loc)); return *this; } - - // Implement isa<T> support. - static inline bool classof(const SVal* V) { - return V->getBaseKind() == LocKind; - } - - static inline bool IsLocType(QualType T) { - return T->isAnyPointerType() || T->isBlockPointerType() || - T->isReferenceType(); - } -}; - -//==------------------------------------------------------------------------==// -// Subclasses of NonLoc. -//==------------------------------------------------------------------------==// - -namespace nonloc { - -enum Kind { ConcreteIntKind, SymbolValKind, SymExprValKind, - LocAsIntegerKind, CompoundValKind, LazyCompoundValKind }; - -class SymbolVal : public NonLoc { -public: - SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {} - - SymbolRef getSymbol() const { - return (const SymbolData*) Data; - } - - static inline bool classof(const SVal* V) { - return V->getBaseKind() == NonLocKind && - V->getSubKind() == SymbolValKind; - } - - static inline bool classof(const NonLoc* V) { - return V->getSubKind() == SymbolValKind; - } -}; - -class SymExprVal : public NonLoc { -public: - SymExprVal(const SymExpr *SE) - : NonLoc(SymExprValKind, reinterpret_cast<const void*>(SE)) {} - - const SymExpr *getSymbolicExpression() const { - return reinterpret_cast<const SymExpr*>(Data); - } - - static inline bool classof(const SVal* V) { - return V->getBaseKind() == NonLocKind && - V->getSubKind() == SymExprValKind; - } - - static inline bool classof(const NonLoc* V) { - return V->getSubKind() == SymExprValKind; - } -}; - -class ConcreteInt : public NonLoc { -public: - ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {} - - const llvm::APSInt& getValue() const { - return *static_cast<const llvm::APSInt*>(Data); - } - - // Transfer functions for binary/unary operations on ConcreteInts. - SVal evalBinOp(ValueManager &ValMgr, BinaryOperator::Opcode Op, - const ConcreteInt& R) const; - - ConcreteInt evalComplement(ValueManager &ValMgr) const; - - ConcreteInt evalMinus(ValueManager &ValMgr) const; - - // Implement isa<T> support. - static inline bool classof(const SVal* V) { - return V->getBaseKind() == NonLocKind && - V->getSubKind() == ConcreteIntKind; - } - - static inline bool classof(const NonLoc* V) { - return V->getSubKind() == ConcreteIntKind; - } -}; - -class LocAsInteger : public NonLoc { - friend class clang::ValueManager; - - LocAsInteger(const std::pair<SVal, uintptr_t>& data) : - NonLoc(LocAsIntegerKind, &data) { - assert (isa<Loc>(data.first)); - } - -public: - - Loc getLoc() const { - return cast<Loc>(((std::pair<SVal, uintptr_t>*) Data)->first); - } - - const Loc& getPersistentLoc() const { - const SVal& V = ((std::pair<SVal, uintptr_t>*) Data)->first; - return cast<Loc>(V); - } - - unsigned getNumBits() const { - return ((std::pair<SVal, unsigned>*) Data)->second; - } - - // Implement isa<T> support. - static inline bool classof(const SVal* V) { - return V->getBaseKind() == NonLocKind && - V->getSubKind() == LocAsIntegerKind; - } - - static inline bool classof(const NonLoc* V) { - return V->getSubKind() == LocAsIntegerKind; - } -}; - -class CompoundVal : public NonLoc { - friend class clang::ValueManager; - - CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {} - -public: - const CompoundValData* getValue() const { - return static_cast<const CompoundValData*>(Data); - } - - typedef llvm::ImmutableList<SVal>::iterator iterator; - iterator begin() const; - iterator end() const; - - static bool classof(const SVal* V) { - return V->getBaseKind() == NonLocKind && V->getSubKind() == CompoundValKind; - } - - static bool classof(const NonLoc* V) { - return V->getSubKind() == CompoundValKind; - } -}; - -class LazyCompoundVal : public NonLoc { - friend class clang::ValueManager; - - LazyCompoundVal(const LazyCompoundValData *D) - : NonLoc(LazyCompoundValKind, D) {} -public: - const LazyCompoundValData *getCVData() const { - return static_cast<const LazyCompoundValData*>(Data); - } - const void *getStore() const; - const TypedRegion *getRegion() const; - - static bool classof(const SVal *V) { - return V->getBaseKind() == NonLocKind && - V->getSubKind() == LazyCompoundValKind; - } - static bool classof(const NonLoc *V) { - return V->getSubKind() == LazyCompoundValKind; - } -}; - -} // end namespace clang::nonloc - -//==------------------------------------------------------------------------==// -// Subclasses of Loc. -//==------------------------------------------------------------------------==// - -namespace loc { - -enum Kind { GotoLabelKind, MemRegionKind, ConcreteIntKind }; - -class GotoLabel : public Loc { -public: - GotoLabel(LabelStmt* Label) : Loc(GotoLabelKind, Label) {} - - const LabelStmt* getLabel() const { - return static_cast<const LabelStmt*>(Data); - } - - static inline bool classof(const SVal* V) { - return V->getBaseKind() == LocKind && - V->getSubKind() == GotoLabelKind; - } - - static inline bool classof(const Loc* V) { - return V->getSubKind() == GotoLabelKind; - } -}; - - -class MemRegionVal : public Loc { -public: - MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {} - - const MemRegion* getRegion() const { - return static_cast<const MemRegion*>(Data); - } - - const MemRegion* StripCasts() const; - - template <typename REGION> - const REGION* getRegionAs() const { - return llvm::dyn_cast<REGION>(getRegion()); - } - - inline bool operator==(const MemRegionVal& R) const { - return getRegion() == R.getRegion(); - } - - inline bool operator!=(const MemRegionVal& R) const { - return getRegion() != R.getRegion(); - } - - // Implement isa<T> support. - static inline bool classof(const SVal* V) { - return V->getBaseKind() == LocKind && - V->getSubKind() == MemRegionKind; - } - - static inline bool classof(const Loc* V) { - return V->getSubKind() == MemRegionKind; - } -}; - -class ConcreteInt : public Loc { -public: - ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {} - - const llvm::APSInt& getValue() const { - return *static_cast<const llvm::APSInt*>(Data); - } - - // Transfer functions for binary/unary operations on ConcreteInts. - SVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op, - const ConcreteInt& R) const; - - // Implement isa<T> support. - static inline bool classof(const SVal* V) { - return V->getBaseKind() == LocKind && - V->getSubKind() == ConcreteIntKind; - } - - static inline bool classof(const Loc* V) { - return V->getSubKind() == ConcreteIntKind; - } -}; - -} // end clang::loc namespace -} // end clang namespace - -namespace llvm { -static inline llvm::raw_ostream& operator<<(llvm::raw_ostream& os, - clang::SVal V) { - V.dumpToStream(os); - return os; -} -} // end llvm namespace -#endif diff --git a/include/clang/Checker/PathSensitive/SValuator.h b/include/clang/Checker/PathSensitive/SValuator.h deleted file mode 100644 index 9192ca7..0000000 --- a/include/clang/Checker/PathSensitive/SValuator.h +++ /dev/null @@ -1,70 +0,0 @@ -// SValuator.h - Construction of SVals from evaluating expressions -*- 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 SValuator, a class that defines the interface for -// "symbolical evaluators" which construct an SVal from an expression. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_SVALUATOR -#define LLVM_CLANG_ANALYSIS_SVALUATOR - -#include "clang/AST/Expr.h" -#include "clang/Checker/PathSensitive/SVals.h" - -namespace clang { - -class GRState; -class ValueManager; - -class SValuator { - friend class ValueManager; -protected: - ValueManager &ValMgr; - -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; - -public: - SValuator(ValueManager &valMgr) : ValMgr(valMgr) {} - virtual ~SValuator() {} - - SVal EvalCast(SVal V, 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, - NonLoc lhs, NonLoc rhs, QualType resultTy) = 0; - - 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, - 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; - - SVal EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op, - SVal L, SVal R, QualType T); - - DefinedOrUnknownSVal EvalEQ(const GRState *ST, DefinedOrUnknownSVal L, - DefinedOrUnknownSVal R); -}; - -SValuator* CreateSimpleSValuator(ValueManager &valMgr); - -} // end clang namespace -#endif diff --git a/include/clang/Checker/PathSensitive/Store.h b/include/clang/Checker/PathSensitive/Store.h deleted file mode 100644 index a1a4184..0000000 --- a/include/clang/Checker/PathSensitive/Store.h +++ /dev/null @@ -1,245 +0,0 @@ -//== Store.h - Interface for maps from Locations to Values ------*- 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 types Store and StoreManager. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_STORE_H -#define LLVM_CLANG_ANALYSIS_STORE_H - -#include "clang/Checker/PathSensitive/MemRegion.h" -#include "clang/Checker/PathSensitive/SVals.h" -#include "clang/Checker/PathSensitive/ValueManager.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/Optional.h" - -namespace clang { - -typedef const void* Store; - -class GRState; -class GRStateManager; -class Stmt; -class Expr; -class ObjCIvarDecl; -class SubRegionMap; -class StackFrameContext; - -class StoreManager { -protected: - ValueManager &ValMgr; - GRStateManager &StateMgr; - - /// MRMgr - Manages region objects associated with this StoreManager. - MemRegionManager &MRMgr; - ASTContext &Ctx; - - StoreManager(GRStateManager &stateMgr); - -public: - virtual ~StoreManager() {} - - /// Return the value bound to specified location in a given state. - /// \param[in] state The analysis state. - /// \param[in] loc The symbolic memory location. - /// \param[in] T An optional type that provides a hint indicating the - /// expected type of the returned value. This is used if the value is - /// lazily computed. - /// \return The value bound to the location \c loc. - virtual SVal Retrieve(Store store, Loc loc, QualType T = QualType()) = 0; - - /// Return a state with the specified value bound to the given location. - /// \param[in] state The analysis state. - /// \param[in] loc The symbolic memory location. - /// \param[in] val The value to bind to location \c loc. - /// \return A pointer to a GRState object that contains the same bindings as - /// \c state with the addition of having the value specified by \c val bound - /// to the location given for \c loc. - virtual Store Bind(Store store, Loc loc, SVal val) = 0; - - virtual Store BindDefault(Store store, const MemRegion *R, SVal V) { - return store; - } - - virtual Store Remove(Store St, Loc L) = 0; - - /// BindCompoundLiteral - Return the store that has the bindings currently - /// in 'store' plus the bindings for the CompoundLiteral. 'R' is the region - /// for the compound literal and 'BegInit' and 'EndInit' represent an - /// array of initializer values. - virtual Store BindCompoundLiteral(Store store, - const CompoundLiteralExpr* cl, - const LocationContext *LC, SVal v) = 0; - - /// getInitialStore - Returns the initial "empty" store representing the - /// value bindings upon entry to an analyzed function. - virtual Store getInitialStore(const LocationContext *InitLoc) = 0; - - /// getRegionManager - Returns the internal RegionManager object that is - /// used to query and manipulate MemRegion objects. - MemRegionManager& getRegionManager() { return MRMgr; } - - /// getSubRegionMap - Returns an opaque map object that clients can query - /// to get the subregions of a given MemRegion object. It is the - // caller's responsibility to 'delete' the returned map. - virtual SubRegionMap *getSubRegionMap(Store store) = 0; - - virtual Loc getLValueVar(const VarDecl *VD, const LocationContext *LC) { - return ValMgr.makeLoc(MRMgr.getVarRegion(VD, LC)); - } - - virtual Loc getLValueString(const StringLiteral* S) { - return ValMgr.makeLoc(MRMgr.getStringRegion(S)); - } - - Loc getLValueCompoundLiteral(const CompoundLiteralExpr* CL, - const LocationContext *LC) { - return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL, LC)); - } - - virtual SVal getLValueIvar(const ObjCIvarDecl* decl, SVal base) { - return getLValueFieldOrIvar(decl, base); - } - - virtual SVal getLValueField(const FieldDecl* D, SVal Base) { - return getLValueFieldOrIvar(D, Base); - } - - virtual SVal getLValueElement(QualType elementType, SVal offset, SVal Base); - - // FIXME: This should soon be eliminated altogether; clients should deal with - // region extents directly. - virtual DefinedOrUnknownSVal getSizeInElements(const GRState *state, - const MemRegion *region, - QualType EleTy) { - return UnknownVal(); - } - - /// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit - /// conversions between arrays and pointers. - virtual SVal ArrayToPointer(Loc Array) = 0; - - class CastResult { - const GRState *state; - const MemRegion *region; - public: - const GRState *getState() const { return state; } - const MemRegion* getRegion() const { return region; } - CastResult(const GRState *s, const MemRegion* r = 0) : state(s), region(r){} - }; - - const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T); - - /// CastRegion - Used by GRExprEngine::VisitCast to handle casts from - /// a MemRegion* to a specific location type. 'R' is the region being - /// casted and 'CastToTy' the result type of the cast. - const MemRegion *CastRegion(const MemRegion *region, QualType CastToTy); - - - /// EvalBinOp - Perform pointer arithmetic. - virtual SVal EvalBinOp(BinaryOperator::Opcode Op, - Loc lhs, NonLoc rhs, QualType resultTy) { - return UnknownVal(); - } - - virtual Store RemoveDeadBindings(Store store, const StackFrameContext *LCtx, - SymbolReaper& SymReaper, - llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0; - - virtual Store BindDecl(Store store, const VarRegion *VR, SVal initVal) = 0; - - virtual Store BindDeclWithNoInit(Store store, const VarRegion *VR) = 0; - - typedef llvm::DenseSet<SymbolRef> InvalidatedSymbols; - typedef llvm::SmallVector<const MemRegion *, 8> InvalidatedRegions; - - /// InvalidateRegions - Clears out the specified regions from the store, - /// marking their values as unknown. Depending on the store, this may also - /// invalidate additional regions that may have changed based on accessing - /// the given regions. Optionally, invalidates non-static globals as well. - /// \param[in] store The initial store - /// \param[in] Begin A pointer to the first region to invalidate. - /// \param[in] End A pointer just past the last region to invalidate. - /// \param[in] E The current statement being evaluated. Used to conjure - /// symbols to mark the values of invalidated regions. - /// \param[in] Count The current block count. Used to conjure - /// symbols to mark the values of invalidated regions. - /// \param[in,out] IS A set to fill with any symbols that are no longer - /// accessible. Pass \c NULL if this information will not be used. - /// \param[in] invalidateGlobals If \c true, any non-static global regions - /// are invalidated as well. - /// \param[in,out] Regions A vector to fill with any regions being - /// invalidated. This should include any regions explicitly invalidated - /// even if they do not currently have bindings. Pass \c NULL if this - /// information will not be used. - virtual Store InvalidateRegions(Store store, - const MemRegion * const *Begin, - const MemRegion * const *End, - const Expr *E, unsigned Count, - InvalidatedSymbols *IS, - bool invalidateGlobals, - InvalidatedRegions *Regions) = 0; - - /// EnterStackFrame - Let the StoreManager to do something when execution - /// engine is about to execute into a callee. - virtual Store EnterStackFrame(const GRState *state, - const StackFrameContext *frame); - - virtual void print(Store store, llvm::raw_ostream& Out, - const char* nl, const char *sep) = 0; - - class BindingsHandler { - public: - virtual ~BindingsHandler(); - virtual bool HandleBinding(StoreManager& SMgr, Store store, - const MemRegion *region, SVal val) = 0; - }; - - /// iterBindings - Iterate over the bindings in the Store. - virtual void iterBindings(Store store, BindingsHandler& f) = 0; - -protected: - const MemRegion *MakeElementRegion(const MemRegion *Base, - QualType pointeeTy, uint64_t index = 0); - - /// CastRetrievedVal - Used by subclasses of StoreManager to implement - /// implicit casts that arise from loads from regions that are reinterpreted - /// as another region. - SVal CastRetrievedVal(SVal val, const TypedRegion *R, QualType castTy, - bool performTestOnly = true); - -private: - SVal getLValueFieldOrIvar(const Decl* D, SVal Base); -}; - -// FIXME: Do we still need this? -/// SubRegionMap - An abstract interface that represents a queryable map -/// between MemRegion objects and their subregions. -class SubRegionMap { -public: - virtual ~SubRegionMap() {} - - class Visitor { - public: - virtual ~Visitor() {} - virtual bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) = 0; - }; - - virtual bool iterSubRegions(const MemRegion *region, Visitor& V) const = 0; -}; - -// FIXME: Do we need to pass GRStateManager anymore? -StoreManager *CreateBasicStoreManager(GRStateManager& StMgr); -StoreManager *CreateRegionStoreManager(GRStateManager& StMgr); -StoreManager *CreateFieldsOnlyRegionStoreManager(GRStateManager& StMgr); -StoreManager *CreateFlatStoreManager(GRStateManager &StMgr); -} // end clang namespace - -#endif diff --git a/include/clang/Checker/PathSensitive/SummaryManager.h b/include/clang/Checker/PathSensitive/SummaryManager.h deleted file mode 100644 index fd23189..0000000 --- a/include/clang/Checker/PathSensitive/SummaryManager.h +++ /dev/null @@ -1,57 +0,0 @@ -//== SummaryManager.h - Generic handling of function summaries --*- 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 SummaryManager and related classes, which provides -// a generic mechanism for managing function summaries. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_CHECKER_SUMMARY -#define LLVM_CLANG_CHECKER_SUMMARY - -#include "llvm/ADT/FoldingSet.h" -#include "llvm/Support/Allocator.h" - -namespace clang { - -namespace summMgr { - - -/* Key kinds: - - - C functions - - C++ functions (name + parameter types) - - ObjC methods: - - Class, selector (class method) - - Class, selector (instance method) - - Category, selector (instance method) - - Protocol, selector (instance method) - - C++ methods - - Class, function name + parameter types + const - */ - -class SummaryKey { - -}; - -} // end namespace clang::summMgr - -class SummaryManagerImpl { - -}; - - -template <typename T> -class SummaryManager : SummaryManagerImpl { - -}; - -} // end clang namespace - -#endif diff --git a/include/clang/Checker/PathSensitive/SymbolManager.h b/include/clang/Checker/PathSensitive/SymbolManager.h deleted file mode 100644 index 26ed0c1..0000000 --- a/include/clang/Checker/PathSensitive/SymbolManager.h +++ /dev/null @@ -1,485 +0,0 @@ -//== SymbolManager.h - Management of Symbolic Values ------------*- 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 SymbolManager, a class that manages symbolic values -// created for use by GRExprEngine and related classes. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_SYMMGR_H -#define LLVM_CLANG_ANALYSIS_SYMMGR_H - -#include "clang/AST/Decl.h" -#include "clang/AST/Expr.h" -#include "clang/Analysis/AnalysisContext.h" -#include "llvm/System/DataTypes.h" -#include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/DenseSet.h" - -namespace llvm { -class BumpPtrAllocator; -class raw_ostream; -} - -namespace clang { - class ASTContext; - class BasicValueFactory; - class MemRegion; - class SubRegion; - class TypedRegion; - class VarRegion; - class StackFrameContext; - -class SymExpr : public llvm::FoldingSetNode { -public: - enum Kind { BEGIN_SYMBOLS, - RegionValueKind, ConjuredKind, DerivedKind, ExtentKind, - MetadataKind, - END_SYMBOLS, - SymIntKind, SymSymKind }; -private: - Kind K; - -protected: - SymExpr(Kind k) : K(k) {} - -public: - virtual ~SymExpr() {} - - Kind getKind() const { return K; } - - void dump() const; - - virtual void dumpToStream(llvm::raw_ostream &os) const = 0; - - virtual QualType getType(ASTContext&) const = 0; - virtual void Profile(llvm::FoldingSetNodeID& profile) = 0; - - // Implement isa<T> support. - static inline bool classof(const SymExpr*) { return true; } -}; - -typedef unsigned SymbolID; - -class SymbolData : public SymExpr { -private: - const SymbolID Sym; - -protected: - SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {} - -public: - virtual ~SymbolData() {} - - SymbolID getSymbolID() const { return Sym; } - - // Implement isa<T> support. - static inline bool classof(const SymExpr* SE) { - Kind k = SE->getKind(); - return k > BEGIN_SYMBOLS && k < END_SYMBOLS; - } -}; - -typedef const SymbolData* SymbolRef; - -// A symbol representing the value of a MemRegion. -class SymbolRegionValue : public SymbolData { - const TypedRegion *R; - -public: - SymbolRegionValue(SymbolID sym, const TypedRegion *r) - : SymbolData(RegionValueKind, sym), R(r) {} - - const TypedRegion* getRegion() const { return R; } - - static void Profile(llvm::FoldingSetNodeID& profile, const TypedRegion* R) { - profile.AddInteger((unsigned) RegionValueKind); - profile.AddPointer(R); - } - - virtual void Profile(llvm::FoldingSetNodeID& profile) { - Profile(profile, R); - } - - void dumpToStream(llvm::raw_ostream &os) const; - - QualType getType(ASTContext&) const; - - // Implement isa<T> support. - static inline bool classof(const SymExpr* SE) { - return SE->getKind() == RegionValueKind; - } -}; - -// A symbol representing the result of an expression. -class SymbolConjured : public SymbolData { - const Stmt* S; - QualType T; - unsigned Count; - const void* SymbolTag; - -public: - SymbolConjured(SymbolID sym, const Stmt* s, QualType t, unsigned count, - const void* symbolTag) - : SymbolData(ConjuredKind, sym), S(s), T(t), Count(count), - SymbolTag(symbolTag) {} - - const Stmt* getStmt() const { return S; } - unsigned getCount() const { return Count; } - const void* getTag() const { return SymbolTag; } - - QualType getType(ASTContext&) const; - - void dumpToStream(llvm::raw_ostream &os) const; - - static void Profile(llvm::FoldingSetNodeID& profile, const Stmt* S, - QualType T, unsigned Count, const void* SymbolTag) { - profile.AddInteger((unsigned) ConjuredKind); - profile.AddPointer(S); - profile.Add(T); - profile.AddInteger(Count); - profile.AddPointer(SymbolTag); - } - - virtual void Profile(llvm::FoldingSetNodeID& profile) { - Profile(profile, S, T, Count, SymbolTag); - } - - // Implement isa<T> support. - static inline bool classof(const SymExpr* SE) { - return SE->getKind() == ConjuredKind; - } -}; - -// A symbol representing the value of a MemRegion whose parent region has -// symbolic value. -class SymbolDerived : public SymbolData { - SymbolRef parentSymbol; - const TypedRegion *R; - -public: - SymbolDerived(SymbolID sym, SymbolRef parent, const TypedRegion *r) - : SymbolData(DerivedKind, sym), parentSymbol(parent), R(r) {} - - SymbolRef getParentSymbol() const { return parentSymbol; } - const TypedRegion *getRegion() const { return R; } - - QualType getType(ASTContext&) const; - - void dumpToStream(llvm::raw_ostream &os) const; - - static void Profile(llvm::FoldingSetNodeID& profile, SymbolRef parent, - const TypedRegion *r) { - profile.AddInteger((unsigned) DerivedKind); - profile.AddPointer(r); - profile.AddPointer(parent); - } - - virtual void Profile(llvm::FoldingSetNodeID& profile) { - Profile(profile, parentSymbol, R); - } - - // Implement isa<T> support. - static inline bool classof(const SymExpr* SE) { - return SE->getKind() == DerivedKind; - } -}; - -/// SymbolExtent - Represents the extent (size in bytes) of a bounded region. -/// Clients should not ask the SymbolManager for a region's extent. Always use -/// SubRegion::getExtent instead -- the value returned may not be a symbol. -class SymbolExtent : public SymbolData { - const SubRegion *R; - -public: - SymbolExtent(SymbolID sym, const SubRegion *r) - : SymbolData(ExtentKind, sym), R(r) {} - - const SubRegion *getRegion() const { return R; } - - QualType getType(ASTContext&) const; - - void dumpToStream(llvm::raw_ostream &os) const; - - static void Profile(llvm::FoldingSetNodeID& profile, const SubRegion *R) { - profile.AddInteger((unsigned) ExtentKind); - profile.AddPointer(R); - } - - virtual void Profile(llvm::FoldingSetNodeID& profile) { - Profile(profile, R); - } - - // Implement isa<T> support. - static inline bool classof(const SymExpr* SE) { - return SE->getKind() == ExtentKind; - } -}; - -/// SymbolMetadata - Represents path-dependent metadata about a specific region. -/// Metadata symbols remain live as long as they are marked as in use before -/// dead-symbol sweeping AND their associated regions are still alive. -/// Intended for use by checkers. -class SymbolMetadata : public SymbolData { - const MemRegion* R; - const Stmt* S; - QualType T; - unsigned Count; - const void* Tag; -public: - SymbolMetadata(SymbolID sym, const MemRegion* r, const Stmt* s, QualType t, - unsigned count, const void* tag) - : SymbolData(MetadataKind, sym), R(r), S(s), T(t), Count(count), Tag(tag) {} - - const MemRegion *getRegion() const { return R; } - const Stmt* getStmt() const { return S; } - unsigned getCount() const { return Count; } - const void* getTag() const { return Tag; } - - QualType getType(ASTContext&) const; - - void dumpToStream(llvm::raw_ostream &os) const; - - static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion *R, - const Stmt *S, QualType T, unsigned Count, - const void *Tag) { - profile.AddInteger((unsigned) MetadataKind); - profile.AddPointer(R); - profile.AddPointer(S); - profile.Add(T); - profile.AddInteger(Count); - profile.AddPointer(Tag); - } - - virtual void Profile(llvm::FoldingSetNodeID& profile) { - Profile(profile, R, S, T, Count, Tag); - } - - // Implement isa<T> support. - static inline bool classof(const SymExpr* SE) { - return SE->getKind() == MetadataKind; - } -}; - -// SymIntExpr - Represents symbolic expression like 'x' + 3. -class SymIntExpr : public SymExpr { - const SymExpr *LHS; - BinaryOperator::Opcode Op; - const llvm::APSInt& RHS; - QualType T; - -public: - SymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op, - const llvm::APSInt& rhs, QualType t) - : SymExpr(SymIntKind), LHS(lhs), Op(op), RHS(rhs), T(t) {} - - // FIXME: We probably need to make this out-of-line to avoid redundant - // generation of virtual functions. - QualType getType(ASTContext& C) const { return T; } - - BinaryOperator::Opcode getOpcode() const { return Op; } - - void dumpToStream(llvm::raw_ostream &os) const; - - const SymExpr *getLHS() const { return LHS; } - const llvm::APSInt &getRHS() const { return RHS; } - - static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs, - BinaryOperator::Opcode op, const llvm::APSInt& rhs, - QualType t) { - ID.AddInteger((unsigned) SymIntKind); - ID.AddPointer(lhs); - ID.AddInteger(op); - ID.AddPointer(&rhs); - ID.Add(t); - } - - void Profile(llvm::FoldingSetNodeID& ID) { - Profile(ID, LHS, Op, RHS, T); - } - - // Implement isa<T> support. - static inline bool classof(const SymExpr* SE) { - return SE->getKind() == SymIntKind; - } -}; - -// SymSymExpr - Represents symbolic expression like 'x' + 'y'. -class SymSymExpr : public SymExpr { - const SymExpr *LHS; - BinaryOperator::Opcode Op; - const SymExpr *RHS; - QualType T; - -public: - SymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, - QualType t) - : SymExpr(SymSymKind), LHS(lhs), Op(op), RHS(rhs), T(t) {} - - BinaryOperator::Opcode getOpcode() const { return Op; } - const SymExpr *getLHS() const { return LHS; } - const SymExpr *getRHS() const { return RHS; } - - // FIXME: We probably need to make this out-of-line to avoid redundant - // generation of virtual functions. - QualType getType(ASTContext& C) const { return T; } - - void dumpToStream(llvm::raw_ostream &os) const; - - static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs, - BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) { - ID.AddInteger((unsigned) SymSymKind); - ID.AddPointer(lhs); - ID.AddInteger(op); - ID.AddPointer(rhs); - ID.Add(t); - } - - void Profile(llvm::FoldingSetNodeID& ID) { - Profile(ID, LHS, Op, RHS, T); - } - - // Implement isa<T> support. - static inline bool classof(const SymExpr* SE) { - return SE->getKind() == SymSymKind; - } -}; - -class SymbolManager { - typedef llvm::FoldingSet<SymExpr> DataSetTy; - DataSetTy DataSet; - unsigned SymbolCounter; - llvm::BumpPtrAllocator& BPAlloc; - BasicValueFactory &BV; - ASTContext& Ctx; - -public: - SymbolManager(ASTContext& ctx, BasicValueFactory &bv, - llvm::BumpPtrAllocator& bpalloc) - : SymbolCounter(0), BPAlloc(bpalloc), BV(bv), Ctx(ctx) {} - - ~SymbolManager(); - - static bool canSymbolicate(QualType T); - - /// Make a unique symbol for MemRegion R according to its kind. - const SymbolRegionValue* getRegionValueSymbol(const TypedRegion* R); - - const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T, - unsigned VisitCount, - const void* SymbolTag = 0); - - const SymbolConjured* getConjuredSymbol(const Expr* E, unsigned VisitCount, - const void* SymbolTag = 0) { - return getConjuredSymbol(E, E->getType(), VisitCount, SymbolTag); - } - - const SymbolDerived *getDerivedSymbol(SymbolRef parentSymbol, - const TypedRegion *R); - - const SymbolExtent *getExtentSymbol(const SubRegion *R); - - const SymbolMetadata* getMetadataSymbol(const MemRegion* R, const Stmt* S, - QualType T, unsigned VisitCount, - const void* SymbolTag = 0); - - const SymIntExpr *getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op, - const llvm::APSInt& rhs, QualType t); - - const SymIntExpr *getSymIntExpr(const SymExpr &lhs, BinaryOperator::Opcode op, - const llvm::APSInt& rhs, QualType t) { - return getSymIntExpr(&lhs, op, rhs, t); - } - - const SymSymExpr *getSymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, - const SymExpr *rhs, QualType t); - - QualType getType(const SymExpr *SE) const { - return SE->getType(Ctx); - } - - ASTContext &getContext() { return Ctx; } - BasicValueFactory &getBasicVals() { return BV; } -}; - -class SymbolReaper { - typedef llvm::DenseSet<SymbolRef> SetTy; - - SetTy TheLiving; - SetTy MetadataInUse; - SetTy TheDead; - const LocationContext *LCtx; - const Stmt *Loc; - SymbolManager& SymMgr; - -public: - SymbolReaper(const LocationContext *ctx, const Stmt *s, SymbolManager& symmgr) - : LCtx(ctx), Loc(s), SymMgr(symmgr) {} - - ~SymbolReaper() {} - - const LocationContext *getLocationContext() const { return LCtx; } - const Stmt *getCurrentStatement() const { return Loc; } - - bool isLive(SymbolRef sym); - bool isLive(const Stmt *ExprVal) const; - bool isLive(const VarRegion *VR) const; - - // markLive - Unconditionally marks a symbol as live. This should never be - // used by checkers, only by the state infrastructure such as the store and - // environment. Checkers should instead use metadata symbols and markInUse. - void markLive(SymbolRef sym); - - // markInUse - Marks a symbol as important to a checker. For metadata symbols, - // this will keep the symbol alive as long as its associated region is also - // live. For other symbols, this has no effect; checkers are not permitted - // to influence the life of other symbols. This should be used before any - // symbol marking has occurred, i.e. in the MarkLiveSymbols callback. - void markInUse(SymbolRef sym); - - // maybeDead - If a symbol is known to be live, marks the symbol as live. - // Otherwise, if the symbol cannot be proven live, it is marked as dead. - // Returns true if the symbol is dead, false if live. - bool maybeDead(SymbolRef sym); - - typedef SetTy::const_iterator dead_iterator; - dead_iterator dead_begin() const { return TheDead.begin(); } - dead_iterator dead_end() const { return TheDead.end(); } - - bool hasDeadSymbols() const { - return !TheDead.empty(); - } - - /// isDead - Returns whether or not a symbol has been confirmed dead. This - /// should only be called once all marking of dead symbols has completed. - /// (For checkers, this means only in the EvalDeadSymbols callback.) - bool isDead(SymbolRef sym) const { - return TheDead.count(sym); - } -}; - -class SymbolVisitor { -public: - // VisitSymbol - A visitor method invoked by - // GRStateManager::scanReachableSymbols. The method returns \c true if - // symbols should continue be scanned and \c false otherwise. - virtual bool VisitSymbol(SymbolRef sym) = 0; - virtual ~SymbolVisitor(); -}; - -} // end clang namespace - -namespace llvm { -static inline llvm::raw_ostream& operator<<(llvm::raw_ostream& os, - const clang::SymExpr *SE) { - SE->dumpToStream(os); - return os; -} -} // end llvm namespace -#endif diff --git a/include/clang/Checker/PathSensitive/ValueManager.h b/include/clang/Checker/PathSensitive/ValueManager.h deleted file mode 100644 index b81e9c1..0000000 --- a/include/clang/Checker/PathSensitive/ValueManager.h +++ /dev/null @@ -1,216 +0,0 @@ -//== ValueManager.h - Aggregate manager of symbols and SVals ----*- 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 ValueManager, a class that manages symbolic values -// and SVals created for use by GRExprEngine and related classes. It -// wraps and owns SymbolManager, MemRegionManager, and BasicValueFactory. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H -#define LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H - -#include "llvm/ADT/OwningPtr.h" -#include "clang/Checker/PathSensitive/MemRegion.h" -#include "clang/Checker/PathSensitive/SVals.h" -#include "clang/Checker/PathSensitive/BasicValueFactory.h" -#include "clang/Checker/PathSensitive/SymbolManager.h" -#include "clang/Checker/PathSensitive/SValuator.h" -#include "clang/AST/ExprCXX.h" - -namespace llvm { class BumpPtrAllocator; } - -namespace clang { - -class GRStateManager; - -class ValueManager { - - ASTContext &Context; - BasicValueFactory BasicVals; - - /// SymMgr - Object that manages the symbol information. - SymbolManager SymMgr; - - /// SVator - SValuator object that creates SVals from expressions. - llvm::OwningPtr<SValuator> SVator; - - MemRegionManager MemMgr; - - GRStateManager &StateMgr; - - const QualType ArrayIndexTy; - const unsigned ArrayIndexWidth; - -public: - ValueManager(llvm::BumpPtrAllocator &alloc, ASTContext &context, - GRStateManager &stateMgr) - : Context(context), BasicVals(context, alloc), - SymMgr(context, BasicVals, alloc), - MemMgr(context, alloc), StateMgr(stateMgr), - ArrayIndexTy(context.IntTy), - ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) { - // FIXME: Generalize later. - SVator.reset(clang::CreateSimpleSValuator(*this)); - } - - // Accessors to submanagers. - - ASTContext &getContext() { return Context; } - const ASTContext &getContext() const { return Context; } - - GRStateManager &getStateManager() { return StateMgr; } - - BasicValueFactory &getBasicValueFactory() { return BasicVals; } - const BasicValueFactory &getBasicValueFactory() const { return BasicVals; } - - SymbolManager &getSymbolManager() { return SymMgr; } - const SymbolManager &getSymbolManager() const { return SymMgr; } - - SValuator &getSValuator() { return *SVator.get(); } - - MemRegionManager &getRegionManager() { return MemMgr; } - const MemRegionManager &getRegionManager() const { return MemMgr; } - - // 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 Expr* E, unsigned VisitCount, - const void* SymbolTag = 0) { - return SymMgr.getConjuredSymbol(E, VisitCount, SymbolTag); - } - - /// makeZeroVal - Construct an SVal representing '0' for the specified type. - DefinedOrUnknownSVal makeZeroVal(QualType T); - - /// getRegionValueSymbolVal - make a unique symbol for value of R. - DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedRegion *R); - - DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag, - const Expr *E, unsigned Count); - DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag, - const Expr *E, QualType T, - unsigned Count); - - DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, - const TypedRegion *R); - - DefinedSVal getMetadataSymbolVal(const void *SymbolTag, const MemRegion *MR, - const Expr *E, QualType T, unsigned Count); - - DefinedSVal getFunctionPointer(const FunctionDecl *FD); - - DefinedSVal getBlockPointer(const BlockDecl *BD, CanQualType locTy, - const LocationContext *LC); - - NonLoc makeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals) { - return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals)); - } - - NonLoc makeLazyCompoundVal(const void *store, const TypedRegion *R) { - return nonloc::LazyCompoundVal(BasicVals.getLazyCompoundValData(store, R)); - } - - NonLoc makeZeroArrayIndex() { - return nonloc::ConcreteInt(BasicVals.getValue(0, ArrayIndexTy)); - } - - NonLoc makeArrayIndex(uint64_t idx) { - return nonloc::ConcreteInt(BasicVals.getValue(idx, ArrayIndexTy)); - } - - SVal convertToArrayIndex(SVal V); - - nonloc::ConcreteInt makeIntVal(const IntegerLiteral* I) { - return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(), - I->getType()->isUnsignedIntegerType())); - } - - nonloc::ConcreteInt makeIntVal(const CXXBoolLiteralExpr *E) { - return E->getValue() ? nonloc::ConcreteInt(BasicVals.getValue(1, 1, true)) - : nonloc::ConcreteInt(BasicVals.getValue(0, 1, true)); - } - - nonloc::ConcreteInt makeIntVal(const llvm::APSInt& V) { - return nonloc::ConcreteInt(BasicVals.getValue(V)); - } - - loc::ConcreteInt makeIntLocVal(const llvm::APSInt &v) { - return loc::ConcreteInt(BasicVals.getValue(v)); - } - - NonLoc makeIntVal(const llvm::APInt& V, bool isUnsigned) { - return nonloc::ConcreteInt(BasicVals.getValue(V, isUnsigned)); - } - - DefinedSVal makeIntVal(uint64_t X, QualType T) { - if (Loc::IsLocType(T)) - return loc::ConcreteInt(BasicVals.getValue(X, T)); - - return nonloc::ConcreteInt(BasicVals.getValue(X, T)); - } - - NonLoc makeIntVal(uint64_t X, bool isUnsigned) { - return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned)); - } - - NonLoc makeIntValWithPtrWidth(uint64_t X, bool isUnsigned) { - return nonloc::ConcreteInt(BasicVals.getIntWithPtrWidth(X, isUnsigned)); - } - - NonLoc makeIntVal(uint64_t X, unsigned BitWidth, bool isUnsigned) { - return nonloc::ConcreteInt(BasicVals.getValue(X, BitWidth, isUnsigned)); - } - - NonLoc makeLocAsInteger(Loc V, unsigned Bits) { - return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(V, Bits)); - } - - NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, - const llvm::APSInt& rhs, QualType T); - - NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, - const SymExpr *rhs, QualType T); - - NonLoc makeTruthVal(bool b, QualType T) { - return nonloc::ConcreteInt(BasicVals.getTruthValue(b, T)); - } - - NonLoc makeTruthVal(bool b) { - return nonloc::ConcreteInt(BasicVals.getTruthValue(b)); - } - - Loc makeNull() { - return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth()); - } - - Loc makeLoc(SymbolRef Sym) { - return loc::MemRegionVal(MemMgr.getSymbolicRegion(Sym)); - } - - Loc makeLoc(const MemRegion* R) { - return loc::MemRegionVal(R); - } - - Loc makeLoc(const AddrLabelExpr* E) { - return loc::GotoLabel(E->getLabel()); - } - - Loc makeLoc(const llvm::APSInt& V) { - return loc::ConcreteInt(BasicVals.getValue(V)); - } -}; -} // end clang namespace -#endif - |