#include "ValueState.h"
#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
+#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
+#include "GRSimpleVals.h"
+
#include "clang/AST/Expr.h"
#include "clang/AST/ASTContext.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
typedef GRIndirectGotoNodeBuilder<GRExprEngine> IndirectGotoNodeBuilder;
typedef GRSwitchNodeBuilder<GRExprEngine> SwitchNodeBuilder;
-
class NodeSet {
typedef llvm::SmallVector<NodeTy*,3> ImplTy;
ImplTy Impl;
/// ValueMgr - Object that manages the data for all created RValues.
ValueManager& ValMgr;
+ /// TF - Object that represents a bundle of transfer functions
+ /// for manipulating and creating RValues.
+ GRTransferFuncs& TF;
+
/// SymMgr - Object that manages the symbol information.
SymbolManager& SymMgr;
bool StateCleaned;
public:
- GRExprEngine(GraphTy& g) : G(g), Liveness(G.getCFG(), G.getFunctionDecl()),
+ GRExprEngine(GraphTy& g) :
+ G(g), Liveness(G.getCFG(), G.getFunctionDecl()),
Builder(NULL),
StateMgr(G.getContext(), G.getAllocator()),
ValMgr(StateMgr.getValueManager()),
+ TF(*(new GRSimpleVals())), // FIXME.
SymMgr(StateMgr.getSymbolManager()),
StmtEntryNode(NULL), CurrentStmt(NULL) {
/// VisitUnaryOperator - Transfer function logic for unary operators.
void VisitUnaryOperator(UnaryOperator* B, NodeTy* Pred, NodeSet& Dst);
+
+ inline RValue EvalCast(ValueManager& ValMgr, RValue R, Expr* CastExpr) {
+ return TF.EvalCast(ValMgr, R, CastExpr);
+ }
+
};
} // end anonymous namespace
NodeTy* N = *I1;
StateTy St = N->getState();
const RValue& V = GetValue(St, E);
- Nodify(Dst, CastE, N, SetValue(St, CastE, V.EvalCast(ValMgr, CastE)));
+ Nodify(Dst, CastE, N, SetValue(St, CastE, EvalCast(ValMgr, V, CastE)));
}
}
Diagnostic& Diag) {
GRCoreEngine<GRExprEngine> Engine(cfg, FD, Ctx);
+ GRExprEngine* CheckerState = &Engine.getCheckerState();
+
+ // Execute the worklist algorithm.
Engine.ExecuteWorkList();
// Look for explicit-Null dereferences and warn about them.
- GRExprEngine* CheckerState = &Engine.getCheckerState();
+
for (GRExprEngine::null_iterator I=CheckerState->null_begin(),
E=CheckerState->null_end(); I!=E; ++I) {
--- /dev/null
+// GRSimpleVals.cpp - Transfer functions for tracking simple values -*- C++ -*--
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This files defines GRSimpleVals, a sub-class of GRTransferFuncs that
+// provides transfer functions for performing simple value tracking with
+// limited support for symbolics.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRSimpleVals.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Transfer function for Casts.
+//===----------------------------------------------------------------------===//
+
+RValue GRSimpleVals::EvalCast(ValueManager& ValMgr, NonLValue X,
+ Expr* CastExpr) {
+
+ if (!isa<nonlval::ConcreteInt>(X))
+ return UnknownVal();
+
+ llvm::APSInt V = cast<nonlval::ConcreteInt>(X).getValue();
+ QualType T = CastExpr->getType();
+ V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
+ V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
+
+ if (CastExpr->getType()->isPointerType())
+ return lval::ConcreteInt(ValMgr.getValue(V));
+ else
+ return nonlval::ConcreteInt(ValMgr.getValue(V));
+}
+
+// Casts.
+
+RValue GRSimpleVals::EvalCast(ValueManager& ValMgr, LValue X, Expr* CastExpr) {
+
+ if (CastExpr->getType()->isPointerType())
+ return X;
+
+ assert (CastExpr->getType()->isIntegerType());
+
+ if (!isa<lval::ConcreteInt>(X))
+ return UnknownVal();
+
+ llvm::APSInt V = cast<lval::ConcreteInt>(X).getValue();
+ QualType T = CastExpr->getType();
+ V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
+ V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
+
+ return nonlval::ConcreteInt(ValMgr.getValue(V));
+}
\ No newline at end of file
--- /dev/null
+// GRSimpleVals.h - Transfer functions for tracking simple values -*- C++ -*--//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This files defines GRSimpleVals, a sub-class of GRTransferFuncs that
+// provides transfer functions for performing simple value tracking with
+// limited support for symbolics.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GRSIMPLEVALS
+#define LLVM_CLANG_ANALYSIS_GRSIMPLEVALS
+
+#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
+
+namespace clang {
+
+class GRSimpleVals : public GRTransferFuncs {
+public:
+ GRSimpleVals() {}
+ virtual ~GRSimpleVals() {}
+
+ virtual RValue EvalCast(ValueManager& ValMgr, NonLValue V, Expr* CastExpr);
+ virtual RValue EvalCast(ValueManager& ValMgr, LValue V, Expr* CastExpr);
+};
+
+
+} // end clang namespace
+
+#endif
--- /dev/null
+//== GRTransferFuncs.cpp - Path-Sens. Transfer Functions Interface -*- C++ -*--=
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This files defines GRTransferFuncs, which provides a base-class that
+// defines an interface for transfer functions used by GRExprEngine.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Transfer function for Casts.
+//===----------------------------------------------------------------------===//
+
+RValue GRTransferFuncs::EvalCast(ValueManager& ValMgr, RValue X,
+ Expr* CastExpr) {
+
+ switch (X.getBaseKind()) {
+ default:
+ assert(false && "Invalid RValue."); break;
+
+ case RValue::LValueKind:
+ return EvalCast(ValMgr, cast<LValue>(X), CastExpr);
+
+ case RValue::NonLValueKind:
+ return EvalCast(ValMgr, cast<NonLValue>(X), CastExpr);
+
+ case RValue::UninitializedKind:
+ case RValue::UnknownKind: break;
+ }
+
+ return X;
+}
return *C;
}
-//===----------------------------------------------------------------------===//
-// Transfer function for Casts.
-//===----------------------------------------------------------------------===//
-RValue RValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
- switch (getBaseKind()) {
- default: assert(false && "Invalid RValue."); break;
- case LValueKind: return cast<LValue>(this)->EvalCast(ValMgr, CastExpr);
- case NonLValueKind: return cast<NonLValue>(this)->EvalCast(ValMgr, CastExpr);
- case UninitializedKind: case UnknownKind: break;
- }
-
- return *this;
-}
//===----------------------------------------------------------------------===//
return ValMgr.getValue(~getValue());
}
- // Casts.
-
-RValue NonLValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
- if (!isa<nonlval::ConcreteInt>(this))
- return UnknownVal();
-
- APSInt V = cast<nonlval::ConcreteInt>(this)->getValue();
- QualType T = CastExpr->getType();
- V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
- V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
-
- if (CastExpr->getType()->isPointerType())
- return lval::ConcreteInt(ValMgr.getValue(V));
- else
- return nonlval::ConcreteInt(ValMgr.getValue(V));
-}
-
// Unary Minus.
NonLValue NonLValue::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
return NonLValue::GetIntTruthValue(ValMgr, true);
}
- // Casts.
-RValue LValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
- if (CastExpr->getType()->isPointerType())
- return *this;
-
- assert (CastExpr->getType()->isIntegerType());
-
- if (!isa<lval::ConcreteInt>(*this))
- return UnknownVal();
-
- APSInt V = cast<lval::ConcreteInt>(this)->getValue();
- QualType T = CastExpr->getType();
- V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
- V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
- return nonlval::ConcreteInt(ValMgr.getValue(V));
-}
//===----------------------------------------------------------------------===//
// Utility methods for constructing Non-LValues.
--- /dev/null
+//== GRTransferFuncs.h - Path-Sens. Transfer Functions Interface -*- C++ -*--=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This files defines GRTransferFuncs, which provides a base-class that
+// defines an interface for transfer functions used by GRExprEngine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GRTF
+#define LLVM_CLANG_ANALYSIS_GRTF
+
+#include "clang/Analysis/PathSensitive/RValues.h"
+
+namespace clang {
+
+class GRTransferFuncs {
+public:
+ GRTransferFuncs() {}
+ virtual ~GRTransferFuncs() {}
+
+ RValue EvalCast(ValueManager& ValMgr, RValue V, Expr* CastExpr);
+ virtual RValue EvalCast(ValueManager& ValMgr, NonLValue V, Expr* CastExpr) =0;
+ virtual RValue EvalCast(ValueManager& ValMgr, LValue V, Expr* CastExpr) = 0;
+
+
+
+};
+
+} // end clang namespace
+
+#endif
/// BufferTy - A temporary buffer to hold a set of RValues.
typedef llvm::SmallVector<RValue,5> BufferTy;
-
-
- RValue EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
unsigned getRawKind() const { return Kind; }
BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
BinaryOperator::Opcode Op,
const NonLValue& RHS) const;
- RValue EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
NonLValue EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const;
NonLValue EvalComplement(ValueManager& ValMgr) const;
RValue EvalBinaryOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
const LValue& RHS) const;
-
- RValue EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
-
+
static LValue GetValue(AddrLabelExpr* E);
// Implement isa<T> support.