aboutsummaryrefslogtreecommitdiff
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.h1
-rw-r--r--include/clang/Analysis/PathSensitive/AnalysisManager.h5
-rw-r--r--include/clang/Analysis/PathSensitive/BugReporter.h16
-rw-r--r--include/clang/Analysis/PathSensitive/BugType.h15
-rw-r--r--include/clang/Analysis/PathSensitive/Checker.h99
-rw-r--r--include/clang/Analysis/PathSensitive/CheckerVisitor.def15
-rw-r--r--include/clang/Analysis/PathSensitive/CheckerVisitor.h36
-rw-r--r--include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h32
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngine.h122
-rw-r--r--include/clang/Analysis/PathSensitive/GRState.h22
-rw-r--r--include/clang/Analysis/PathSensitive/GRWorkList.h7
-rw-r--r--include/clang/Analysis/PathSensitive/MemRegion.h2
-rw-r--r--include/clang/Analysis/PathSensitive/SVals.h4
-rw-r--r--include/clang/Analysis/PathSensitive/Store.h6
14 files changed, 171 insertions, 211 deletions
diff --git a/include/clang/Analysis/PathSensitive/AnalysisContext.h b/include/clang/Analysis/PathSensitive/AnalysisContext.h
index 66e850a91444..9b58f745f0a5 100644
--- a/include/clang/Analysis/PathSensitive/AnalysisContext.h
+++ b/include/clang/Analysis/PathSensitive/AnalysisContext.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
+#include "clang/AST/Stmt.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/DenseMap.h"
diff --git a/include/clang/Analysis/PathSensitive/AnalysisManager.h b/include/clang/Analysis/PathSensitive/AnalysisManager.h
index 488334623b34..18eae9ac9f14 100644
--- a/include/clang/Analysis/PathSensitive/AnalysisManager.h
+++ b/include/clang/Analysis/PathSensitive/AnalysisManager.h
@@ -37,7 +37,6 @@ class AnalysisManager : public BugReporterData {
enum AnalysisScope { ScopeTU, ScopeDecl } AScope;
- bool DisplayedFunction;
bool VisualizeEGDot;
bool VisualizeEGUbi;
bool PurgeDead;
@@ -62,7 +61,7 @@ public:
: Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd),
CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),
- AScope(ScopeDecl), DisplayedFunction(!displayProgress),
+ AScope(ScopeDecl),
VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge),
EagerlyAssume(eager), TrimGraph(trim) {}
@@ -120,8 +119,6 @@ public:
bool shouldEagerlyAssume() const { return EagerlyAssume; }
- void DisplayFunction(Decl *D);
-
CFG *getCFG(Decl const *D) {
return AnaCtxMgr.getContext(D)->getCFG();
}
diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h
index 914118cb430d..f4297350ec70 100644
--- a/include/clang/Analysis/PathSensitive/BugReporter.h
+++ b/include/clang/Analysis/PathSensitive/BugReporter.h
@@ -81,10 +81,10 @@ public:
getOriginalNode(const ExplodedNode* N) = 0;
};
- BugReport(BugType& bt, const char* desc, const ExplodedNode *n)
+ BugReport(BugType& bt, llvm::StringRef desc, const ExplodedNode *n)
: BT(bt), Description(desc), EndNode(n) {}
- BugReport(BugType& bt, const char* shortDesc, const char* desc,
+ BugReport(BugType& bt, llvm::StringRef shortDesc, llvm::StringRef desc,
const ExplodedNode *n)
: BT(bt), ShortDescription(shortDesc), Description(desc), EndNode(n) {}
@@ -193,11 +193,11 @@ public:
class RangedBugReport : public BugReport {
std::vector<SourceRange> Ranges;
public:
- RangedBugReport(BugType& D, const char* description, ExplodedNode *n)
+ RangedBugReport(BugType& D, llvm::StringRef description, ExplodedNode *n)
: BugReport(D, description, n) {}
- RangedBugReport(BugType& D, const char *shortDescription,
- const char *description, ExplodedNode *n)
+ RangedBugReport(BugType& D, llvm::StringRef shortDescription,
+ llvm::StringRef description, ExplodedNode *n)
: BugReport(D, shortDescription, description, n) {}
~RangedBugReport();
@@ -229,11 +229,11 @@ private:
Creators creators;
public:
- EnhancedBugReport(BugType& D, const char* description, ExplodedNode *n)
+ EnhancedBugReport(BugType& D, llvm::StringRef description, ExplodedNode *n)
: RangedBugReport(D, description, n) {}
- EnhancedBugReport(BugType& D, const char *shortDescription,
- const char *description, ExplodedNode *n)
+ EnhancedBugReport(BugType& D, llvm::StringRef shortDescription,
+ llvm::StringRef description, ExplodedNode *n)
: RangedBugReport(D, shortDescription, description, n) {}
~EnhancedBugReport() {}
diff --git a/include/clang/Analysis/PathSensitive/BugType.h b/include/clang/Analysis/PathSensitive/BugType.h
index 242b8e9afebe..8303dee49afa 100644
--- a/include/clang/Analysis/PathSensitive/BugType.h
+++ b/include/clang/Analysis/PathSensitive/BugType.h
@@ -23,6 +23,7 @@ class BugReportEquivClass;
class BugReporter;
class BuiltinBugReport;
class BugReporterContext;
+class ExplodedNode;
class GRExprEngine;
class BugType {
@@ -59,21 +60,27 @@ public:
};
class BuiltinBug : public BugType {
- GRExprEngine &Eng;
+ GRExprEngine *Eng;
protected:
const std::string desc;
public:
+ BuiltinBug(const char *name, const char *description)
+ : BugType(name, "Logic error"), Eng(0), desc(description) {}
+
+ BuiltinBug(const char *name)
+ : BugType(name, "Logic error"), Eng(0), desc(name) {}
+
BuiltinBug(GRExprEngine *eng, const char* n, const char* d)
- : BugType(n, "Logic error"), Eng(*eng), desc(d) {}
+ : BugType(n, "Logic error"), Eng(eng), desc(d) {}
BuiltinBug(GRExprEngine *eng, const char* n)
- : BugType(n, "Logic error"), Eng(*eng), desc(n) {}
+ : BugType(n, "Logic error"), 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); }
+ void FlushReports(BugReporter& BR) { FlushReportsImpl(BR, *Eng); }
virtual void registerInitialVisitors(BugReporterContext& BRC,
const ExplodedNode* N,
diff --git a/include/clang/Analysis/PathSensitive/Checker.h b/include/clang/Analysis/PathSensitive/Checker.h
index 4fc0a617ecf0..b7ed20fab250 100644
--- a/include/clang/Analysis/PathSensitive/Checker.h
+++ b/include/clang/Analysis/PathSensitive/Checker.h
@@ -39,22 +39,19 @@ class CheckerContext {
SaveAndRestore<const void*> OldTag;
SaveAndRestore<ProgramPoint::Kind> OldPointKind;
SaveOr OldHasGen;
+ const GRState *state;
public:
- CheckerContext(ExplodedNodeSet &dst,
- GRStmtNodeBuilder &builder,
- GRExprEngine &eng,
- ExplodedNode *pred,
- const void *tag, bool preVisit)
+ CheckerContext(ExplodedNodeSet &dst, GRStmtNodeBuilder &builder,
+ GRExprEngine &eng, ExplodedNode *pred,
+ const void *tag, ProgramPoint::Kind K,
+ const GRState *st = 0)
: Dst(dst), B(builder), Eng(eng), Pred(pred),
- OldSink(B.BuildSinks), OldTag(B.Tag),
- OldPointKind(B.PointKind), OldHasGen(B.HasGeneratedNode) {
- //assert(Dst.empty()); // This is a fake assertion.
- // See GRExprEngine::CheckerVisit(), CurrSet is repeatedly used.
- B.Tag = tag;
- if (preVisit)
- B.PointKind = ProgramPoint::PreStmtKind;
- }
+ OldSink(B.BuildSinks),
+ OldTag(B.Tag, tag),
+ OldPointKind(B.PointKind, K),
+ OldHasGen(B.HasGeneratedNode),
+ state(st) {}
~CheckerContext() {
if (!B.BuildSinks && !B.HasGeneratedNode)
@@ -64,10 +61,15 @@ public:
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 B.GetState(Pred); }
+ const GRState *getState() { return state ? state : B.GetState(Pred); }
ASTContext &getASTContext() {
return Eng.getContext();
@@ -76,6 +78,10 @@ public:
BugReporter &getBugReporter() {
return Eng.getBugReporter();
}
+
+ SourceManager &getSourceManager() {
+ return getBugReporter().getSourceManager();
+ }
ExplodedNode *GenerateNode(const Stmt *S, bool markAsSink = false) {
return GenerateNode(S, getState(), markAsSink);
@@ -104,50 +110,69 @@ class Checker {
private:
friend class GRExprEngine;
+ // FIXME: Remove the 'tag' option.
void GR_Visit(ExplodedNodeSet &Dst,
GRStmtNodeBuilder &Builder,
GRExprEngine &Eng,
- const Stmt *stmt,
+ const Stmt *S,
ExplodedNode *Pred, void *tag, bool isPrevisit) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag, isPrevisit);
- assert(isPrevisit && "Only previsit supported for now.");
- _PreVisit(C, stmt);
+ CheckerContext C(Dst, Builder, Eng, Pred, tag,
+ isPrevisit ? ProgramPoint::PreStmtKind :
+ ProgramPoint::PostStmtKind);
+ if (isPrevisit)
+ _PreVisit(C, S);
+ else
+ _PostVisit(C, S);
}
+ // FIXME: Remove the 'tag' option.
void GR_VisitBind(ExplodedNodeSet &Dst,
GRStmtNodeBuilder &Builder, GRExprEngine &Eng,
const Stmt *AssignE,
const Stmt *StoreE, ExplodedNode *Pred, void *tag,
SVal location, SVal val,
bool isPrevisit) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag, isPrevisit);
+ CheckerContext C(Dst, Builder, Eng, Pred, tag,
+ isPrevisit ? ProgramPoint::PreStmtKind :
+ ProgramPoint::PostStmtKind);
assert(isPrevisit && "Only previsit supported for now.");
PreVisitBind(C, AssignE, StoreE, location, val);
}
-
-public:
- virtual ~Checker() {}
- 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;
+ // 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, state);
+ VisitLocation(C, S, location);
}
-
- virtual void PreVisitBind(CheckerContext &C,
- const Stmt *AssignE, const Stmt *StoreE,
- SVal location, SVal val) {}
- virtual ExplodedNode *CheckType(QualType T, ExplodedNode *Pred,
- const GRState *state, Stmt *S,
- GRExprEngine &Eng) {
- return Pred;
+ 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, Pred->getState());
+ EvalDeadSymbols(C, S, 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 *AssignE,
+ const Stmt *StoreE, SVal location, SVal val) {}
+ virtual void EvalDeadSymbols(CheckerContext &C, const Stmt *S,
+ SymbolReaper &SymReaper) {}
+ virtual void EvalEndPath(GREndPathNodeBuilder &B, void *tag,
+ GRExprEngine &Eng) {}
};
-
} // end clang namespace
#endif
diff --git a/include/clang/Analysis/PathSensitive/CheckerVisitor.def b/include/clang/Analysis/PathSensitive/CheckerVisitor.def
index ff6528dae8f5..090a5d397549 100644
--- a/include/clang/Analysis/PathSensitive/CheckerVisitor.def
+++ b/include/clang/Analysis/PathSensitive/CheckerVisitor.def
@@ -11,8 +11,19 @@
//
//===---------------------------------------------------------------------===//
+#ifdef PREVISIT
+PREVISIT(ArraySubscriptExpr)
+PREVISIT(BinaryOperator)
PREVISIT(CallExpr)
+PREVISIT(CastExpr)
+PREVISIT(DeclStmt)
PREVISIT(ObjCMessageExpr)
-PREVISIT(BinaryOperator)
-
+PREVISIT(ReturnStmt)
#undef PREVISIT
+#endif
+
+#ifdef POSTVISIT
+POSTVISIT(CallExpr)
+#undef POSTVISIT
+#endif
+
diff --git a/include/clang/Analysis/PathSensitive/CheckerVisitor.h b/include/clang/Analysis/PathSensitive/CheckerVisitor.h
index e74f49c9a761..7cef17eb6591 100644
--- a/include/clang/Analysis/PathSensitive/CheckerVisitor.h
+++ b/include/clang/Analysis/PathSensitive/CheckerVisitor.h
@@ -27,8 +27,12 @@ namespace clang {
template<typename ImplClass>
class CheckerVisitor : public Checker {
public:
- virtual void _PreVisit(CheckerContext &C, const Stmt *stmt) {
- PreVisit(C, stmt);
+ 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) {
@@ -36,10 +40,19 @@ public:
default:
assert(false && "Unsupport statement.");
return;
+
+ case Stmt::ImplicitCastExprClass:
+ case Stmt::ExplicitCastExprClass:
+ 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) \
case Stmt::NAME ## Class:\
static_cast<ImplClass*>(this)->PreVisit ## NAME(C,static_cast<const NAME*>(S));\
@@ -47,13 +60,30 @@ break;
#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
}
}
+
+ void PostVisit(CheckerContext &C, const Stmt *S) {
+ switch (S->getStmtClass()) {
+ default:
+ assert(false && "Unsupport statement.");
+ return;
+#define POSTVISIT(NAME) \
+case Stmt::NAME ## Class:\
+static_cast<ImplClass*>(this)->\
+PostVisit ## NAME(C,static_cast<const NAME*>(S));\
+break;
+#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
+ }
+ }
#define PREVISIT(NAME) \
void PreVisit ## NAME(CheckerContext &C, const NAME* S) {}
#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
+
+#define POSTVISIT(NAME) \
+void PostVisit ## NAME(CheckerContext &C, const NAME* S) {}
+#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
};
} // end clang namespace
#endif
-
diff --git a/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h b/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h
index 688cf641491d..a84183e7f27f 100644
--- a/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h
+++ b/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h
@@ -16,38 +16,16 @@
#ifndef LLVM_CLANG_DEREFCHECKER
#define LLVM_CLANG_DEREFCHECKER
-#include "clang/Analysis/PathSensitive/Checker.h"
-#include "clang/Analysis/PathSensitive/BugType.h"
+#include <utility>
namespace clang {
+class GRExprEngine;
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();
-};
+std::pair<ExplodedNode * const *, ExplodedNode * const *>
+GetImplicitNullDereferences(GRExprEngine &Eng);
} // end clang namespace
+
#endif
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h
index 25e47038d72c..1b6d0bdf9c10 100644
--- a/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h
@@ -111,14 +111,6 @@ public:
// was larger than sizeof(void *) (an undefined value).
ErrorNodes NilReceiverLargerThanVoidPtrRetImplicit;
- /// RetsStackAddr - Nodes in the ExplodedGraph that result from returning
- /// the address of a stack variable.
- ErrorNodes RetsStackAddr;
-
- /// RetsUndef - Nodes in the ExplodedGraph that result from returning
- /// an undefined value.
- ErrorNodes RetsUndef;
-
/// UndefBranches - Nodes in the ExplodedGraph that result from
/// taking a branch based on an undefined value.
ErrorNodes UndefBranches;
@@ -131,22 +123,10 @@ public:
// calling a function with the attribute "noreturn".
ErrorNodes NoReturnCalls;
- /// ImplicitBadSizedVLA - Nodes in the ExplodedGraph that result from
- /// constructing a zero-sized VLA where the size may be zero.
- ErrorNodes ImplicitBadSizedVLA;
-
- /// ExplicitBadSizedVLA - Nodes in the ExplodedGraph that result from
- /// constructing a zero-sized VLA where the size must be zero.
- ErrorNodes ExplicitBadSizedVLA;
-
/// UndefResults - Nodes in the ExplodedGraph where the operands are defined
/// by the result is not. Excludes divide-by-zero errors.
ErrorNodes UndefResults;
- /// BadCalls - Nodes in the ExplodedGraph resulting from calls to function
- /// pointers that are NULL (or other constants) or Undefined.
- ErrorNodes BadCalls;
-
/// UndefReceiver - Nodes in the ExplodedGraph resulting from message
/// ObjC message expressions where the receiver is undefined (uninitialized).
ErrorNodes UndefReceivers;
@@ -156,14 +136,6 @@ public:
/// value.
UndefArgsTy MsgExprUndefArgs;
- /// OutOfBoundMemAccesses - Nodes in the ExplodedGraph resulting from
- /// out-of-bound memory accesses where the index MAY be out-of-bound.
- ErrorNodes ImplicitOOBMemAccesses;
-
- /// OutOfBoundMemAccesses - Nodes in the ExplodedGraph resulting from
- /// out-of-bound memory accesses where the index MUST be out-of-bound.
- ErrorNodes ExplicitOOBMemAccesses;
-
public:
GRExprEngine(AnalysisManager &mgr);
@@ -223,58 +195,10 @@ public:
return static_cast<CHECKER*>(lookupChecker(CHECKER::getTag()));
}
- bool isRetStackAddr(const ExplodedNode* N) const {
- return N->isSink() && RetsStackAddr.count(const_cast<ExplodedNode*>(N)) != 0;
- }
-
- bool isUndefControlFlow(const ExplodedNode* N) const {
- return N->isSink() && UndefBranches.count(const_cast<ExplodedNode*>(N)) != 0;
- }
-
- bool isUndefStore(const ExplodedNode* N) const {
- return N->isSink() && UndefStores.count(const_cast<ExplodedNode*>(N)) != 0;
- }
-
- bool isImplicitNullDeref(const ExplodedNode* N) const {
- return false;
- }
-
- bool isExplicitNullDeref(const ExplodedNode* N) const {
- return false;
- }
-
- bool isUndefDeref(const ExplodedNode* N) const {
- return false;
- }
-
bool isNoReturnCall(const ExplodedNode* N) const {
return N->isSink() && NoReturnCalls.count(const_cast<ExplodedNode*>(N)) != 0;
}
- bool isUndefResult(const ExplodedNode* N) const {
- return N->isSink() && UndefResults.count(const_cast<ExplodedNode*>(N)) != 0;
- }
-
- bool isBadCall(const ExplodedNode* N) const {
- return false;
- }
-
- bool isUndefArg(const ExplodedNode* N) const {
- return false;
- }
-
- bool isUndefReceiver(const ExplodedNode* N) const {
- return N->isSink() && UndefReceivers.count(const_cast<ExplodedNode*>(N)) != 0;
- }
-
- typedef ErrorNodes::iterator ret_stackaddr_iterator;
- ret_stackaddr_iterator ret_stackaddr_begin() { return RetsStackAddr.begin(); }
- ret_stackaddr_iterator ret_stackaddr_end() { return RetsStackAddr.end(); }
-
- typedef ErrorNodes::iterator ret_undef_iterator;
- ret_undef_iterator ret_undef_begin() { return RetsUndef.begin(); }
- ret_undef_iterator ret_undef_end() { return RetsUndef.end(); }
-
typedef ErrorNodes::iterator undef_branch_iterator;
undef_branch_iterator undef_branches_begin() { return UndefBranches.begin(); }
undef_branch_iterator undef_branches_end() { return UndefBranches.end(); }
@@ -305,10 +229,6 @@ public:
undef_result_iterator undef_results_begin() { return UndefResults.begin(); }
undef_result_iterator undef_results_end() { return UndefResults.end(); }
- typedef ErrorNodes::iterator bad_calls_iterator;
- bad_calls_iterator bad_calls_begin() { return BadCalls.begin(); }
- bad_calls_iterator bad_calls_end() { return BadCalls.end(); }
-
typedef UndefArgsTy::iterator undef_arg_iterator;
undef_arg_iterator msg_expr_undef_arg_begin() {
return MsgExprUndefArgs.begin();
@@ -327,20 +247,6 @@ public:
return UndefReceivers.end();
}
- typedef ErrorNodes::iterator oob_memacc_iterator;
- oob_memacc_iterator implicit_oob_memacc_begin() {
- return ImplicitOOBMemAccesses.begin();
- }
- oob_memacc_iterator implicit_oob_memacc_end() {
- return ImplicitOOBMemAccesses.end();
- }
- oob_memacc_iterator explicit_oob_memacc_begin() {
- return ExplicitOOBMemAccesses.begin();
- }
- oob_memacc_iterator explicit_oob_memacc_end() {
- return ExplicitOOBMemAccesses.end();
- }
-
void AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C);
void AddCheck(GRSimpleAPICheck* A);
@@ -368,10 +274,7 @@ public:
/// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path
/// nodes when the control reaches the end of a function.
- void ProcessEndPath(GREndPathNodeBuilder& builder) {
- getTF().EvalEndPath(*this, builder);
- StateMgr.EndPath(builder.getState());
- }
+ void ProcessEndPath(GREndPathNodeBuilder& builder);
GRStateManager& getStateManager() { return StateMgr; }
const GRStateManager& getStateManager() const { return StateMgr; }
@@ -516,9 +419,6 @@ protected:
void VisitUnaryOperator(UnaryOperator* B, ExplodedNode* Pred, ExplodedNodeSet& Dst,
bool asLValue);
- const GRState* CheckDivideZero(Expr* Ex, const GRState* St, ExplodedNode* Pred,
- SVal Denom);
-
/// 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.
@@ -553,15 +453,11 @@ public:
}
protected:
- void EvalCall(ExplodedNodeSet& Dst, CallExpr* CE, SVal L, ExplodedNode* Pred);
-
void EvalObjCMessageExpr(ExplodedNodeSet& Dst, ObjCMessageExpr* ME, ExplodedNode* Pred) {
assert (Builder && "GRStmtNodeBuilder must be defined.");
getTF().EvalObjCMessageExpr(Dst, *this, *Builder, ME, Pred);
}
- void EvalReturn(ExplodedNodeSet& Dst, ReturnStmt* s, ExplodedNode* Pred);
-
const GRState* MarkBranch(const GRState* St, Stmt* Terminator,
bool branchTaken);
@@ -573,16 +469,22 @@ protected:
bool atDeclInit = false);
public:
+ // FIXME: 'tag' should be removed, and a LocationContext should be used
+ // instead.
void EvalLoad(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
- const GRState* St, SVal location, const void *tag = 0);
+ const GRState* St, SVal location, const void *tag = 0,
+ QualType LoadTy = QualType());
- ExplodedNode* EvalLocation(Stmt* Ex, ExplodedNode* Pred,
+ // FIXME: 'tag' should be removed, and a LocationContext should be used
+ // instead.
+ void EvalLocation(ExplodedNodeSet &Dst, Stmt *S, ExplodedNode* Pred,
const GRState* St, SVal location,
- const void *tag = 0);
+ const void *tag, bool isLoad);
+ // FIXME: 'tag' should be removed, and a LocationContext should be used
+ // instead.
void EvalStore(ExplodedNodeSet& Dst, Expr* AssignE, Expr* StoreE,
- ExplodedNode* Pred,
- const GRState* St, SVal TargetLV, SVal Val,
+ ExplodedNode* Pred, const GRState* St, SVal TargetLV, SVal Val,
const void *tag = 0);
};
diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h
index 8678ca9b5b9b..ef0c36c44d9f 100644
--- a/include/clang/Analysis/PathSensitive/GRState.h
+++ b/include/clang/Analysis/PathSensitive/GRState.h
@@ -195,6 +195,9 @@ public:
//
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,
@@ -330,12 +333,6 @@ public:
void printStdErr() const;
void printDOT(llvm::raw_ostream& Out) const;
-
- // Tags used for the Generic Data Map.
- struct NullDerefTag {
- static int TagInt;
- typedef const SVal* data_type;
- };
};
class GRStateSet {
@@ -403,10 +400,6 @@ private:
/// Alloc - A BumpPtrAllocator to allocate states.
llvm::BumpPtrAllocator& Alloc;
- /// CurrentStmt - The block-level statement currently being visited. This
- /// is set by GRExprEngine.
- Stmt* CurrentStmt;
-
/// TF - Object that represents a bundle of transfer functions
/// for manipulating and creating SVals.
GRTransferFuncs* TF;
@@ -583,6 +576,15 @@ inline const GRState *GRState::Assume(DefinedOrUnknownSVal Cond,
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::AssumeInBound(DefinedOrUnknownSVal Idx,
DefinedOrUnknownSVal UpperBound,
diff --git a/include/clang/Analysis/PathSensitive/GRWorkList.h b/include/clang/Analysis/PathSensitive/GRWorkList.h
index 17b83fdf9fdc..857fa316911f 100644
--- a/include/clang/Analysis/PathSensitive/GRWorkList.h
+++ b/include/clang/Analysis/PathSensitive/GRWorkList.h
@@ -16,16 +16,19 @@
#define LLVM_CLANG_ANALYSIS_GRWORKLIST
#include "clang/Analysis/PathSensitive/GRBlockCounter.h"
+#include <cstddef>
namespace clang {
-
+
+class CFGBlock;
+class ExplodedNode;
class ExplodedNodeImpl;
class GRWorkListUnit {
ExplodedNode* Node;
GRBlockCounter Counter;
CFGBlock* Block;
- unsigned BlockIdx;
+ unsigned BlockIdx; // This is the index of the next statement.
public:
GRWorkListUnit(ExplodedNode* N, GRBlockCounter C,
diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h
index 0e487691a891..06d0d976df01 100644
--- a/include/clang/Analysis/PathSensitive/MemRegion.h
+++ b/include/clang/Analysis/PathSensitive/MemRegion.h
@@ -77,6 +77,8 @@ public:
const MemRegion *getBaseRegion() const;
+ const MemRegion *StripCasts() const;
+
bool hasStackStorage() const;
bool hasParametersStorage() const;
diff --git a/include/clang/Analysis/PathSensitive/SVals.h b/include/clang/Analysis/PathSensitive/SVals.h
index 4ba3c7396822..8b5cf40e29cb 100644
--- a/include/clang/Analysis/PathSensitive/SVals.h
+++ b/include/clang/Analysis/PathSensitive/SVals.h
@@ -96,6 +96,8 @@ public:
return getRawKind() > UnknownKind;
}
+ bool isConstant() const;
+
bool isZeroConstant() const;
/// hasConjuredSymbol - If this SVal wraps a conjured symbol, return true;
@@ -434,7 +436,7 @@ public:
return static_cast<MemRegion*>(Data);
}
- const MemRegion* getBaseRegion() const;
+ const MemRegion* StripCasts() const;
template <typename REGION>
const REGION* getRegionAs() const {
diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h
index 6ca2e9e9aa68..55fa83d9ecc3 100644
--- a/include/clang/Analysis/PathSensitive/Store.h
+++ b/include/clang/Analysis/PathSensitive/Store.h
@@ -102,7 +102,8 @@ public:
virtual SVal getLValueElement(QualType elementType, SVal offset, SVal Base)=0;
// FIXME: Make out-of-line.
- virtual SVal getSizeInElements(const GRState *state, const MemRegion *region){
+ virtual DefinedOrUnknownSVal getSizeInElements(const GRState *state,
+ const MemRegion *region) {
return UnknownVal();
}
@@ -180,8 +181,7 @@ protected:
/// CastRetrievedVal - Used by subclasses of StoreManager to implement
/// implicit casts that arise from loads from regions that are reinterpreted
/// as another region.
- SValuator::CastResult CastRetrievedVal(SVal val, const GRState *state,
- const TypedRegion *R, QualType castTy);
+ SVal CastRetrievedVal(SVal val, const TypedRegion *R, QualType castTy);
};
// FIXME: Do we still need this?