diff options
Diffstat (limited to 'include/clang/Analysis/PathSensitive')
16 files changed, 425 insertions, 107 deletions
diff --git a/include/clang/Analysis/PathSensitive/AnalysisContext.h b/include/clang/Analysis/PathSensitive/AnalysisContext.h index 8e02ccf..66e850a 100644 --- a/include/clang/Analysis/PathSensitive/AnalysisContext.h +++ b/include/clang/Analysis/PathSensitive/AnalysisContext.h @@ -80,6 +80,8 @@ protected: : Kind(k), Ctx(ctx), Parent(parent) {} public: + virtual ~LocationContext() {} + ContextKind getKind() const { return Kind; } AnalysisContext *getAnalysisContext() const { return Ctx; } @@ -102,7 +104,7 @@ public: return Ctx->getSelfDecl(); } - void Profile(llvm::FoldingSetNodeID &ID) { + virtual void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Kind, Ctx, Parent); } @@ -119,10 +121,13 @@ public: StackFrameContext(AnalysisContext *ctx, const LocationContext *parent, const Stmt *s) : LocationContext(StackFrame, ctx, parent), CallSite(s) {} + + virtual ~StackFrameContext() {} + Stmt const *getCallSite() const { return CallSite; } - void Profile(llvm::FoldingSetNodeID &ID) { + virtual void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getAnalysisContext(), getParent(), CallSite); } @@ -141,8 +146,10 @@ public: ScopeContext(AnalysisContext *ctx, const LocationContext *parent, const Stmt *s) : LocationContext(Scope, ctx, parent), Enter(s) {} + + virtual ~ScopeContext() {} - void Profile(llvm::FoldingSetNodeID &ID) { + virtual void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getAnalysisContext(), getParent(), Enter); } diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h index 1434fce..914118c 100644 --- a/include/clang/Analysis/PathSensitive/BugReporter.h +++ b/include/clang/Analysis/PathSensitive/BugReporter.h @@ -19,6 +19,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Analysis/PathSensitive/GRState.h" #include "clang/Analysis/PathSensitive/ExplodedGraph.h" +#include "clang/Analysis/PathSensitive/BugType.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallString.h" @@ -183,38 +184,6 @@ public: const_iterator end() const { return const_iterator(Reports.end()); } }; -class BugType { -private: - const std::string Name; - const std::string Category; - llvm::FoldingSet<BugReportEquivClass> EQClasses; - friend class BugReporter; - bool SuppressonSink; -public: - BugType(const char *name, const char* cat) - : Name(name), Category(cat), SuppressonSink(false) {} - virtual ~BugType(); - - // FIXME: Should these be made strings as well? - const std::string& getName() const { return Name; } - const std::string& getCategory() const { return Category; } - - /// isSuppressOnSink - Returns true if bug reports associated with this bug - /// type should be suppressed if the end node of the report is post-dominated - /// by a sink node. - bool isSuppressOnSink() const { return SuppressonSink; } - void setSuppressOnSink(bool x) { SuppressonSink = x; } - - virtual void FlushReports(BugReporter& BR); - - typedef llvm::FoldingSet<BugReportEquivClass>::iterator iterator; - iterator begin() { return EQClasses.begin(); } - iterator end() { return EQClasses.end(); } - - typedef llvm::FoldingSet<BugReportEquivClass>::const_iterator const_iterator; - const_iterator begin() const { return EQClasses.begin(); } - const_iterator end() const { return EQClasses.end(); } -}; //===----------------------------------------------------------------------===// // Specialized subclasses of BugReport. diff --git a/include/clang/Analysis/PathSensitive/BugType.h b/include/clang/Analysis/PathSensitive/BugType.h new file mode 100644 index 0000000..46b3edd --- /dev/null +++ b/include/clang/Analysis/PathSensitive/BugType.h @@ -0,0 +1,86 @@ +//===--- BugType.h - Bug Information Desciption ----------------*- 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 BugType, a class representing a bug type. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_BUGTYPE +#define LLVM_CLANG_ANALYSIS_BUGTYPE + +#include <llvm/ADT/FoldingSet.h> +#include <string> + +namespace clang { + +class BugReportEquivClass; +class BugReporter; +class BuiltinBugReport; +class BugReporterContext; +class GRExprEngine; + +class BugType { +private: + const std::string Name; + const std::string Category; + llvm::FoldingSet<BugReportEquivClass> EQClasses; + friend class BugReporter; + bool SuppressonSink; +public: + BugType(const char *name, const char* cat) + : Name(name), Category(cat), SuppressonSink(false) {} + virtual ~BugType(); + + // FIXME: Should these be made strings as well? + const std::string& getName() const { return Name; } + const std::string& getCategory() const { return Category; } + + /// isSuppressOnSink - Returns true if bug reports associated with this bug + /// type should be suppressed if the end node of the report is post-dominated + /// by a sink node. + bool isSuppressOnSink() const { return SuppressonSink; } + void setSuppressOnSink(bool x) { SuppressonSink = x; } + + virtual void FlushReports(BugReporter& BR); + + typedef llvm::FoldingSet<BugReportEquivClass>::iterator iterator; + iterator begin() { return EQClasses.begin(); } + iterator end() { return EQClasses.end(); } + + typedef llvm::FoldingSet<BugReportEquivClass>::const_iterator const_iterator; + const_iterator begin() const { return EQClasses.begin(); } + const_iterator end() const { return EQClasses.end(); } +}; + +class BuiltinBug : public BugType { + GRExprEngine &Eng; +protected: + const std::string desc; +public: + BuiltinBug(GRExprEngine *eng, const char* n, const char* d) + : BugType(n, "Logic errors"), Eng(*eng), desc(d) {} + + BuiltinBug(GRExprEngine *eng, const char* n) + : BugType(n, "Logic errors"), Eng(*eng), desc(n) {} + + const std::string &getDescription() const { return desc; } + + virtual void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {} + + void FlushReports(BugReporter& BR) { FlushReportsImpl(BR, Eng); } + + virtual void registerInitialVisitors(BugReporterContext& BRC, + const ExplodedNode* N, + BuiltinBugReport *R) {} + + template <typename ITER> void Emit(BugReporter& BR, ITER I, ITER E); +}; + +} // end clang namespace +#endif diff --git a/include/clang/Analysis/PathSensitive/Checker.h b/include/clang/Analysis/PathSensitive/Checker.h index 4e00d69c..3bef08d 100644 --- a/include/clang/Analysis/PathSensitive/Checker.h +++ b/include/clang/Analysis/PathSensitive/Checker.h @@ -72,6 +72,10 @@ public: ASTContext &getASTContext() { return Eng.getContext(); } + + BugReporter &getBugReporter() { + return Eng.getBugReporter(); + } ExplodedNode *GenerateNode(const Stmt *S, bool markAsSink = false) { return GenerateNode(S, getState(), markAsSink); @@ -104,16 +108,42 @@ private: GRStmtNodeBuilder &Builder, GRExprEngine &Eng, const Stmt *stmt, - ExplodedNode *Pred, bool isPrevisit) { - CheckerContext C(Dst, Builder, Eng, Pred, getTag(), isPrevisit); + ExplodedNode *Pred, void *tag, bool isPrevisit) { + CheckerContext C(Dst, Builder, Eng, Pred, tag, isPrevisit); assert(isPrevisit && "Only previsit supported for now."); _PreVisit(C, stmt); } + void GR_VisitBind(ExplodedNodeSet &Dst, + GRStmtNodeBuilder &Builder, GRExprEngine &Eng, + const Stmt *stmt, ExplodedNode *Pred, void *tag, + SVal location, SVal val, + bool isPrevisit) { + CheckerContext C(Dst, Builder, Eng, Pred, tag, isPrevisit); + assert(isPrevisit && "Only previsit supported for now."); + PreVisitBind(C, stmt, location, val); + } + public: virtual ~Checker() {} - virtual void _PreVisit(CheckerContext &C, const Stmt *stmt) = 0; - virtual const void *getTag() = 0; + virtual void _PreVisit(CheckerContext &C, const Stmt *ST) {} + + // This is a previsit which takes a node returns a node. + virtual ExplodedNode *CheckLocation(const Stmt *S, ExplodedNode *Pred, + const GRState *state, SVal V, + GRExprEngine &Eng) { + return Pred; + } + + virtual void PreVisitBind(CheckerContext &C, const Stmt *ST, + SVal location, SVal val) {} + + virtual ExplodedNode *CheckType(QualType T, ExplodedNode *Pred, + const GRState *state, Stmt *S, + GRExprEngine &Eng) { + return Pred; + } + }; } // end clang namespace diff --git a/include/clang/Analysis/PathSensitive/Checkers/AttrNonNullChecker.h b/include/clang/Analysis/PathSensitive/Checkers/AttrNonNullChecker.h new file mode 100644 index 0000000..007ec09 --- /dev/null +++ b/include/clang/Analysis/PathSensitive/Checkers/AttrNonNullChecker.h @@ -0,0 +1,28 @@ +//===--- AttrNonNullChecker.h - Undefined arguments checker ----*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This defines AttrNonNullChecker, a builtin check in GRExprEngine that +// performs checks for arguments declared to have nonnull attribute. +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/PathSensitive/CheckerVisitor.h" + +namespace clang { + +class AttrNonNullChecker : public CheckerVisitor<AttrNonNullChecker> { + BugType *BT; + +public: + AttrNonNullChecker() : BT(0) {} + static void *getTag(); + void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE); +}; + +} diff --git a/include/clang/Analysis/PathSensitive/Checkers/BadCallChecker.h b/include/clang/Analysis/PathSensitive/Checkers/BadCallChecker.h new file mode 100644 index 0000000..70f3c44 --- /dev/null +++ b/include/clang/Analysis/PathSensitive/Checkers/BadCallChecker.h @@ -0,0 +1,30 @@ +//===--- BadCallChecker.h - Bad call checker --------------------*- C++ -*--==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This defines BadCallChecker, a builtin check in GRExprEngine that performs +// checks for bad callee at call sites. +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/PathSensitive/CheckerVisitor.h" + +namespace clang { + +class BadCallChecker : public CheckerVisitor<BadCallChecker> { + BuiltinBug *BT; + +public: + BadCallChecker() : BT(0) {} + + static void *getTag(); + + void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE); +}; + +} diff --git a/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h b/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h new file mode 100644 index 0000000..688cf64 --- /dev/null +++ b/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h @@ -0,0 +1,53 @@ +//== NullDerefChecker.h - Null dereference checker --------------*- C++ -*--==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This defines NullDerefChecker and UndefDerefChecker, two builtin checks +// in GRExprEngine that check for null and undefined pointers at loads +// and stores. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_DEREFCHECKER +#define LLVM_CLANG_DEREFCHECKER + +#include "clang/Analysis/PathSensitive/Checker.h" +#include "clang/Analysis/PathSensitive/BugType.h" + +namespace clang { + +class ExplodedNode; + +class NullDerefChecker : public Checker { + BuiltinBug *BT; + llvm::SmallVector<ExplodedNode*, 2> ImplicitNullDerefNodes; + +public: + NullDerefChecker() : BT(0) {} + ExplodedNode *CheckLocation(const Stmt *S, ExplodedNode *Pred, + const GRState *state, SVal V,GRExprEngine &Eng); + + static void *getTag(); + typedef llvm::SmallVectorImpl<ExplodedNode*>::iterator iterator; + iterator implicit_nodes_begin() { return ImplicitNullDerefNodes.begin(); } + iterator implicit_nodes_end() { return ImplicitNullDerefNodes.end(); } +}; + +class UndefDerefChecker : public Checker { + BuiltinBug *BT; +public: + UndefDerefChecker() : BT(0) {} + + ExplodedNode *CheckLocation(const Stmt *S, ExplodedNode *Pred, + const GRState *state, SVal V, GRExprEngine &Eng); + + static void *getTag(); +}; + +} // end clang namespace +#endif diff --git a/include/clang/Analysis/PathSensitive/Checkers/DivZeroChecker.h b/include/clang/Analysis/PathSensitive/Checkers/DivZeroChecker.h new file mode 100644 index 0000000..317e43a --- /dev/null +++ b/include/clang/Analysis/PathSensitive/Checkers/DivZeroChecker.h @@ -0,0 +1,28 @@ +//== DivZeroChecker.h - Division by zero checker ----------------*- C++ -*--==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This defines DivZeroChecker, a builtin check in GRExprEngine that performs +// checks for division by zeros. +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/PathSensitive/CheckerVisitor.h" + +namespace clang { + +class DivZeroChecker : public CheckerVisitor<DivZeroChecker> { + BuiltinBug *BT; +public: + DivZeroChecker() : BT(0) {} + + static void *getTag(); + void PreVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B); +}; + +} diff --git a/include/clang/Analysis/PathSensitive/Checkers/UndefinedArgChecker.h b/include/clang/Analysis/PathSensitive/Checkers/UndefinedArgChecker.h new file mode 100644 index 0000000..7f4e7d5 --- /dev/null +++ b/include/clang/Analysis/PathSensitive/Checkers/UndefinedArgChecker.h @@ -0,0 +1,34 @@ +//===--- UndefinedArgChecker.h - Undefined arguments checker ----*- C++ -*--==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This defines BadCallChecker, a builtin check in GRExprEngine that performs +// checks for undefined arguments. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_UNDEFARGCHECKER +#define LLVM_CLANG_UNDEFARGCHECKER + +#include "clang/Analysis/PathSensitive/CheckerVisitor.h" + +namespace clang { + +class UndefinedArgChecker : public CheckerVisitor<UndefinedArgChecker> { + BugType *BT; + +public: + UndefinedArgChecker() : BT(0) {} + + static void *getTag(); + + void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE); +}; + +} +#endif diff --git a/include/clang/Analysis/PathSensitive/Checkers/UndefinedAssignmentChecker.h b/include/clang/Analysis/PathSensitive/Checkers/UndefinedAssignmentChecker.h new file mode 100644 index 0000000..7fee501 --- /dev/null +++ b/include/clang/Analysis/PathSensitive/Checkers/UndefinedAssignmentChecker.h @@ -0,0 +1,32 @@ +//===--- UndefinedAssignmentChecker.h ---------------------------*- C++ -*--==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This defines UndefinedAssginmentChecker, a builtin check in GRExprEngine that +// checks for assigning undefined values. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_UNDEFASSIGNMENTCHECKER +#define LLVM_CLANG_UNDEFASSIGNMENTCHECKER + +#include "clang/Analysis/PathSensitive/CheckerVisitor.h" + +namespace clang { +class UndefinedAssignmentChecker + : public CheckerVisitor<UndefinedAssignmentChecker> { + BugType *BT; +public: + UndefinedAssignmentChecker() : BT(0) {} + static void *getTag(); + virtual void PreVisitBind(CheckerContext &C, const Stmt *S, SVal location, + SVal val); +}; +} +#endif + diff --git a/include/clang/Analysis/PathSensitive/Checkers/VLASizeChecker.h b/include/clang/Analysis/PathSensitive/Checkers/VLASizeChecker.h new file mode 100644 index 0000000..b339b3d --- /dev/null +++ b/include/clang/Analysis/PathSensitive/Checkers/VLASizeChecker.h @@ -0,0 +1,39 @@ +//=== VLASizeChecker.h - Undefined dereference checker ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This defines two VLASizeCheckers, a builtin check in GRExprEngine that +// performs checks for declaration of VLA of undefined or zero size. +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/PathSensitive/Checker.h" + +namespace clang { + +class UndefSizedVLAChecker : public Checker { + BugType *BT; + +public: + UndefSizedVLAChecker() : BT(0) {} + static void *getTag(); + ExplodedNode *CheckType(QualType T, ExplodedNode *Pred, + const GRState *state, Stmt *S, GRExprEngine &Eng); +}; + +class ZeroSizedVLAChecker : public Checker { + BugType *BT; + +public: + ZeroSizedVLAChecker() : BT(0) {} + static void *getTag(); + ExplodedNode *CheckType(QualType T, ExplodedNode *Pred, + const GRState *state, Stmt *S, GRExprEngine &Eng); +}; + +} diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index e5c61e6..2f2a11a 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -75,7 +75,12 @@ class GRExprEngine : public GRSubEngine { Selector RaiseSel; llvm::OwningPtr<GRSimpleAPICheck> BatchAuditor; - std::vector<Checker*> Checkers; + + typedef llvm::DenseMap<void *, unsigned> CheckerMap; + CheckerMap CheckerM; + + typedef std::vector<std::pair<void *, Checker*> >CheckersOrdered; + CheckersOrdered Checkers; /// BR - The BugReporter associated with this engine. It is important that // this object be placed at the very end of member variables so that its @@ -126,18 +131,6 @@ public: // calling a function with the attribute "noreturn". ErrorNodes NoReturnCalls; - /// ImplicitNullDeref - Nodes in the ExplodedGraph that result from - /// taking a dereference on a symbolic pointer that MAY be NULL. - ErrorNodes ImplicitNullDeref; - - /// ExplicitNullDeref - Nodes in the ExplodedGraph that result from - /// taking a dereference on a symbolic pointer that MUST be NULL. - ErrorNodes ExplicitNullDeref; - - /// UndefDeref - Nodes in the ExplodedGraph that result from - /// taking a dereference on an undefined value. - ErrorNodes UndefDeref; - /// ImplicitBadSizedVLA - Nodes in the ExplodedGraph that result from /// constructing a zero-sized VLA where the size may be zero. ErrorNodes ImplicitBadSizedVLA; @@ -158,10 +151,6 @@ public: /// ObjC message expressions where the receiver is undefined (uninitialized). ErrorNodes UndefReceivers; - /// UndefArg - Nodes in the ExplodedGraph resulting from calls to functions - /// where a pass-by-value argument has an undefined value. - UndefArgsTy UndefArgs; - /// MsgExprUndefArgs - Nodes in the ExplodedGraph resulting from /// message expressions where a pass-by-value argument has an undefined /// value. @@ -195,6 +184,8 @@ public: BugReporter& getBugReporter() { return BR; } + GRStmtNodeBuilder &getBuilder() { assert(Builder); return *Builder; } + /// setTransferFunctions void setTransferFunctions(GRTransferFuncs* tf); @@ -217,8 +208,19 @@ public: void RegisterInternalChecks(); - void registerCheck(Checker *check) { - Checkers.push_back(check); + 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())); } bool isRetStackAddr(const ExplodedNode* N) const { @@ -234,15 +236,15 @@ public: } bool isImplicitNullDeref(const ExplodedNode* N) const { - return N->isSink() && ImplicitNullDeref.count(const_cast<ExplodedNode*>(N)) != 0; + return false; } bool isExplicitNullDeref(const ExplodedNode* N) const { - return N->isSink() && ExplicitNullDeref.count(const_cast<ExplodedNode*>(N)) != 0; + return false; } bool isUndefDeref(const ExplodedNode* N) const { - return N->isSink() && UndefDeref.count(const_cast<ExplodedNode*>(N)) != 0; + return false; } bool isNoReturnCall(const ExplodedNode* N) const { @@ -254,13 +256,11 @@ public: } bool isBadCall(const ExplodedNode* N) const { - return N->isSink() && BadCalls.count(const_cast<ExplodedNode*>(N)) != 0; + return false; } bool isUndefArg(const ExplodedNode* N) const { - return N->isSink() && - (UndefArgs.find(const_cast<ExplodedNode*>(N)) != UndefArgs.end() || - MsgExprUndefArgs.find(const_cast<ExplodedNode*>(N)) != MsgExprUndefArgs.end()); + return false; } bool isUndefReceiver(const ExplodedNode* N) const { @@ -279,17 +279,6 @@ public: undef_branch_iterator undef_branches_begin() { return UndefBranches.begin(); } undef_branch_iterator undef_branches_end() { return UndefBranches.end(); } - typedef ErrorNodes::iterator null_deref_iterator; - null_deref_iterator null_derefs_begin() { return ExplicitNullDeref.begin(); } - null_deref_iterator null_derefs_end() { return ExplicitNullDeref.end(); } - - null_deref_iterator implicit_null_derefs_begin() { - return ImplicitNullDeref.begin(); - } - null_deref_iterator implicit_null_derefs_end() { - return ImplicitNullDeref.end(); - } - typedef ErrorNodes::iterator nil_receiver_struct_ret_iterator; nil_receiver_struct_ret_iterator nil_receiver_struct_ret_begin() { @@ -312,10 +301,6 @@ public: return NilReceiverLargerThanVoidPtrRetExplicit.end(); } - typedef ErrorNodes::iterator undef_deref_iterator; - undef_deref_iterator undef_derefs_begin() { return UndefDeref.begin(); } - undef_deref_iterator undef_derefs_end() { return UndefDeref.end(); } - typedef ErrorNodes::iterator undef_result_iterator; undef_result_iterator undef_results_begin() { return UndefResults.begin(); } undef_result_iterator undef_results_end() { return UndefResults.end(); } @@ -325,9 +310,6 @@ public: bad_calls_iterator bad_calls_end() { return BadCalls.end(); } typedef UndefArgsTy::iterator undef_arg_iterator; - undef_arg_iterator undef_arg_begin() { return UndefArgs.begin(); } - undef_arg_iterator undef_arg_end() { return UndefArgs.end(); } - undef_arg_iterator msg_expr_undef_arg_begin() { return MsgExprUndefArgs.begin(); } @@ -427,7 +409,12 @@ public: protected: /// CheckerVisit - Dispatcher for performing checker-specific logic /// at specific statements. - void CheckerVisit(Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src, bool isPrevisit); + void CheckerVisit(Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src, + bool isPrevisit); + + void CheckerVisitBind(Stmt *S, 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. @@ -456,7 +443,8 @@ protected: ExplodedNode* Pred, ExplodedNodeSet& Dst); /// VisitBinaryOperator - Transfer function logic for binary operators. - void VisitBinaryOperator(BinaryOperator* B, ExplodedNode* Pred, ExplodedNodeSet& Dst); + void VisitBinaryOperator(BinaryOperator* B, ExplodedNode* Pred, + ExplodedNodeSet& Dst, bool asLValue); /// VisitCall - Transfer function for function calls. @@ -578,8 +566,9 @@ protected: /// 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, Expr* Ex, ExplodedNode* Pred, - const GRState* St, SVal location, SVal Val); + void EvalBind(ExplodedNodeSet& Dst, Stmt* Ex, ExplodedNode* Pred, + const GRState* St, SVal location, SVal Val, + bool atDeclInit = false); public: void EvalLoad(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred, diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h index d8b9d56..8678ca9 100644 --- a/include/clang/Analysis/PathSensitive/GRState.h +++ b/include/clang/Analysis/PathSensitive/GRState.h @@ -26,7 +26,7 @@ #include "clang/AST/ASTContext.h" #include "clang/Analysis/Analyses/LiveVariables.h" #include "llvm/Support/Casting.h" -#include "llvm/Support/DataTypes.h" +#include "llvm/System/DataTypes.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/ImmutableMap.h" @@ -219,11 +219,9 @@ public: const GRState *BindExpr(const Stmt *S, SVal V, bool Invalidate = true) const; - const GRState *bindDecl(const VarDecl *VD, const LocationContext *LC, - SVal V) const; + const GRState *bindDecl(const VarRegion *VR, SVal V) const; - const GRState *bindDeclWithNoInit(const VarDecl *VD, - const LocationContext *LC) const; + const GRState *bindDeclWithNoInit(const VarRegion *VR) const; const GRState *bindLoc(Loc location, SVal V) const; @@ -602,15 +600,12 @@ inline const GRState *GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL return getStateManager().StoreMgr->BindCompoundLiteral(this, CL, V); } -inline const GRState *GRState::bindDecl(const VarDecl* VD, - const LocationContext *LC, - SVal IVal) const { - return getStateManager().StoreMgr->BindDecl(this, VD, LC, IVal); +inline const GRState *GRState::bindDecl(const VarRegion* VR, SVal IVal) const { + return getStateManager().StoreMgr->BindDecl(this, VR, IVal); } -inline const GRState *GRState::bindDeclWithNoInit(const VarDecl* VD, - const LocationContext *LC) const { - return getStateManager().StoreMgr->BindDeclWithNoInit(this, VD, LC); +inline const GRState *GRState::bindDeclWithNoInit(const VarRegion* VR) const { + return getStateManager().StoreMgr->BindDeclWithNoInit(this, VR); } inline const GRState *GRState::bindLoc(Loc LV, SVal V) const { diff --git a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h index 5f7b2cb..40c1ed3 100644 --- a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h +++ b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h @@ -23,7 +23,6 @@ namespace clang { class GRExprEngine; -class BugReporter; class ObjCMessageExpr; class GRStmtNodeBuilderRef; @@ -33,7 +32,7 @@ public: virtual ~GRTransferFuncs() {} virtual void RegisterPrinters(std::vector<GRState::Printer*>& Printers) {} - virtual void RegisterChecks(BugReporter& BR) {} + virtual void RegisterChecks(GRExprEngine& Eng) {} // Calls. @@ -78,7 +77,7 @@ public: virtual const GRState* EvalAssume(const GRState *state, SVal Cond, bool Assumption) { return state; - } + } }; GRTransferFuncs *CreateCallInliner(ASTContext &ctx); diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index 7a462c5..6ca2e9e 100644 --- a/include/clang/Analysis/PathSensitive/Store.h +++ b/include/clang/Analysis/PathSensitive/Store.h @@ -134,12 +134,11 @@ public: SymbolReaper& SymReaper, llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0; - virtual const GRState *BindDecl(const GRState *ST, const VarDecl *VD, - const LocationContext *LC, SVal initVal) = 0; + virtual const GRState *BindDecl(const GRState *ST, const VarRegion *VR, + SVal initVal) = 0; virtual const GRState *BindDeclWithNoInit(const GRState *ST, - const VarDecl *VD, - const LocationContext *LC) = 0; + const VarRegion *VR) = 0; typedef llvm::DenseSet<SymbolRef> InvalidatedSymbols; diff --git a/include/clang/Analysis/PathSensitive/SymbolManager.h b/include/clang/Analysis/PathSensitive/SymbolManager.h index d3996c6..167a102 100644 --- a/include/clang/Analysis/PathSensitive/SymbolManager.h +++ b/include/clang/Analysis/PathSensitive/SymbolManager.h @@ -18,7 +18,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" #include "clang/Analysis/Analyses/LiveVariables.h" -#include "llvm/Support/DataTypes.h" +#include "llvm/System/DataTypes.h" #include "llvm/Support/Allocator.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/DenseSet.h" |