summaryrefslogtreecommitdiffstats
path: root/include/clang/Analysis/PathSensitive
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Analysis/PathSensitive')
-rw-r--r--include/clang/Analysis/PathSensitive/AnalysisContext.h13
-rw-r--r--include/clang/Analysis/PathSensitive/BugReporter.h33
-rw-r--r--include/clang/Analysis/PathSensitive/BugType.h86
-rw-r--r--include/clang/Analysis/PathSensitive/Checker.h38
-rw-r--r--include/clang/Analysis/PathSensitive/Checkers/AttrNonNullChecker.h28
-rw-r--r--include/clang/Analysis/PathSensitive/Checkers/BadCallChecker.h30
-rw-r--r--include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h53
-rw-r--r--include/clang/Analysis/PathSensitive/Checkers/DivZeroChecker.h28
-rw-r--r--include/clang/Analysis/PathSensitive/Checkers/UndefinedArgChecker.h34
-rw-r--r--include/clang/Analysis/PathSensitive/Checkers/UndefinedAssignmentChecker.h32
-rw-r--r--include/clang/Analysis/PathSensitive/Checkers/VLASizeChecker.h39
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngine.h85
-rw-r--r--include/clang/Analysis/PathSensitive/GRState.h19
-rw-r--r--include/clang/Analysis/PathSensitive/GRTransferFuncs.h5
-rw-r--r--include/clang/Analysis/PathSensitive/Store.h7
-rw-r--r--include/clang/Analysis/PathSensitive/SymbolManager.h2
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"
OpenPOWER on IntegriCloud