aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/GRExprEngine.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-02-14 01:43:44 +0000
committerTed Kremenek <kremenek@apple.com>2009-02-14 01:43:44 +0000
commit41573ebf8fb971f40fa8a3e20648362c359b4916 (patch)
tree819d4b68e8463bfab03d015c4c894a72d4fc4d8f /lib/Analysis/GRExprEngine.cpp
parent13f5f6e4796607e7bebfed1c09d9e5d4248fce9e (diff)
Static analyzer:
- Added a new 'node builder' class called GRStmtNodeBuilderRef (name may change). This is essentially a smart reference to a GRStmtNodeBuilder object that keeps track of the current context (predecessor node, GRExprEngine object, etc.) The idea is to gradually simplify the interface between GRExprEngine and GRTransferFuncs using this new builder (i.e., passing 1 argument instead of 5). It also handles some of the "auto-transition" for node creation, simplifying some of the logic in GRExprEngine itself. - Used GRStmtBuilderRef to replace GRTransferFuncs::EvalStore with GRTransferFuncs::EvalBind. The new EvalBind method will be used at any arbitrary places where a binding between a location and value takes place. Moreover, GRTransferFuncs no longer has the responsibility to request StoreManager to do the binding; this is now in GRExprEngine::EvalBind. All GRTransferFuncs::EvalBind does is checker-specific logic (which can be a no-op). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64525 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/GRExprEngine.cpp')
-rw-r--r--lib/Analysis/GRExprEngine.cpp54
1 files changed, 22 insertions, 32 deletions
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index a52437c343..f0e93de219 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -14,6 +14,8 @@
//===----------------------------------------------------------------------===//
#include "clang/Analysis/PathSensitive/GRExprEngine.h"
+#include "clang/Analysis/PathSensitive/GRExprEngineBuilders.h"
+
#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/Support/Streams.h"
@@ -125,28 +127,6 @@ GRExprEngine::~GRExprEngine() {
// Utility methods.
//===----------------------------------------------------------------------===//
-// SaveAndRestore - A utility class that uses RIIA to save and restore
-// the value of a variable.
-template<typename T>
-struct VISIBILITY_HIDDEN SaveAndRestore {
- SaveAndRestore(T& x) : X(x), old_value(x) {}
- ~SaveAndRestore() { X = old_value; }
- T get() { return old_value; }
-
- T& X;
- T old_value;
-};
-
-// SaveOr - Similar to SaveAndRestore. Operates only on bools; the old
-// value of a variable is saved, and during the dstor the old value is
-// or'ed with the new value.
-struct VISIBILITY_HIDDEN SaveOr {
- SaveOr(bool& x) : X(x), old_value(x) { x = false; }
- ~SaveOr() { X |= old_value; }
-
- bool& X;
- bool old_value;
-};
void GRExprEngine::setTransferFunctions(GRTransferFuncs* tf) {
StateMgr.TF = tf;
@@ -920,17 +900,27 @@ void GRExprEngine::VisitMemberExpr(MemberExpr* M, NodeTy* Pred,
void GRExprEngine::EvalBind(NodeSet& Dst, Expr* Ex, NodeTy* Pred,
const GRState* state, SVal location, SVal Val) {
- unsigned size = Dst.size();
- SaveAndRestore<bool> OldSink(Builder->BuildSinks);
- SaveOr OldHasGen(Builder->HasGeneratedNode);
-
- getTF().EvalStore(Dst, *this, *Builder, Ex, Pred, state, location, Val);
+ const GRState* newState = 0;
+
+ if (location.isUnknown()) {
+ // We know that the new state will be the same as the old state since
+ // the location of the binding is "unknown". Consequently, there
+ // is no reason to just create a new node.
+ newState = state;
+ }
+ else {
+ // We are binding to a value other than 'unknown'. Perform the binding
+ // using the StoreManager.
+ newState = StateMgr.BindLoc(state, cast<Loc>(location), Val);
+ }
- // Handle the case where no nodes where generated. Auto-generate that
- // contains the updated state if we aren't generating sinks.
- if (!Builder->BuildSinks && Dst.size() == size && !Builder->HasGeneratedNode)
- getTF().GRTransferFuncs::EvalStore(Dst, *this, *Builder, Ex, Pred, state,
- location, Val);
+ // The next thing to do is check if the GRTransferFuncs object wants to
+ // update the state based on the new binding. If the GRTransferFunc object
+ // doesn't do anything, just auto-propagate the current state.
+ GRStmtNodeBuilderRef BuilderRef(Dst, *Builder, *this, Pred, newState, Ex,
+ newState != state);
+
+ getTF().EvalBind(BuilderRef, location, Val);
}
/// EvalStore - Handle the semantics of a store via an assignment.