summaryrefslogtreecommitdiffstats
path: root/clang/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
commite68c0fcfb239eef2c8468bb8c32e97fe9f58e7be (patch)
tree2c05a2b40fb871be2e72a7812d89ba12bb05d7d9 /clang/lib/Analysis/GRExprEngine.cpp
parent30c22d86e8f549e9e97313bea55809702da56fb8 (diff)
downloadbcm5719-llvm-e68c0fcfb239eef2c8468bb8c32e97fe9f58e7be.tar.gz
bcm5719-llvm-e68c0fcfb239eef2c8468bb8c32e97fe9f58e7be.zip
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). llvm-svn: 64525
Diffstat (limited to 'clang/lib/Analysis/GRExprEngine.cpp')
-rw-r--r--clang/lib/Analysis/GRExprEngine.cpp54
1 files changed, 22 insertions, 32 deletions
diff --git a/clang/lib/Analysis/GRExprEngine.cpp b/clang/lib/Analysis/GRExprEngine.cpp
index a52437c343e..f0e93de2193 100644
--- a/clang/lib/Analysis/GRExprEngine.cpp
+++ b/clang/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.
OpenPOWER on IntegriCloud