[cfe-commits] r47183 - in /cfe/trunk: Analysis/ExplodedGraph.cpp Analysis/GRExprEngine.cpp Analysis/RValues.cpp Analysis/ValueState.cpp include/clang/Analysis/PathSensitive/ExplodedGraph.h include/clang/Analysis/PathSensitive/GRExprEngine.h include/clang/Analysis/PathSensitive/GRTransferFuncs.h include/clang/Analysis/PathSensitive/RValues.h
Ted Kremenek
kremenek at apple.com
Fri Feb 15 14:09:30 PST 2008
Author: kremenek
Date: Fri Feb 15 16:09:30 2008
New Revision: 47183
URL: http://llvm.org/viewvc/llvm-project?rev=47183&view=rev
Log:
Simplified transfer function logic for ++/-- operators.
Added more boilerplate transfer function support for pointer arithmetic.
Added more pretty-printing support for symbolic constraints.
Added transfer function support for handling enum values.
Minor pointer types cleanup in ExplodedGraphImpl.
Modified:
cfe/trunk/Analysis/ExplodedGraph.cpp
cfe/trunk/Analysis/GRExprEngine.cpp
cfe/trunk/Analysis/RValues.cpp
cfe/trunk/Analysis/ValueState.cpp
cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h
cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
cfe/trunk/include/clang/Analysis/PathSensitive/RValues.h
Modified: cfe/trunk/Analysis/ExplodedGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/ExplodedGraph.cpp?rev=47183&r1=47182&r2=47183&view=diff
==============================================================================
--- cfe/trunk/Analysis/ExplodedGraph.cpp (original)
+++ cfe/trunk/Analysis/ExplodedGraph.cpp Fri Feb 15 16:09:30 2008
@@ -75,8 +75,7 @@
// of the FoldingSets are nodes allocated from the BumpPtrAllocator,
// so all of those will get nuked when that object is destroyed.
for (EdgeNodeSetMap::iterator I=Nodes.begin(), E=Nodes.end(); I!=E; ++I) {
- llvm::FoldingSet<ExplodedNodeImpl>* ENodes =
- reinterpret_cast<llvm::FoldingSet<ExplodedNodeImpl>*>(I->second);
+ llvm::FoldingSet<ExplodedNodeImpl>* ENodes = I->second;
for (llvm::FoldingSet<ExplodedNodeImpl>::iterator
I=ENodes->begin(), E=ENodes->end(); I!=E; ++I)
Modified: cfe/trunk/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRExprEngine.cpp?rev=47183&r1=47182&r2=47183&view=diff
==============================================================================
--- cfe/trunk/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/Analysis/GRExprEngine.cpp Fri Feb 15 16:09:30 2008
@@ -387,8 +387,7 @@
StateTy St = Pred->getState();
- Nodify(Dst, D, Pred,
- SetValue(St, D, GetValue(St, lval::DeclVal(D->getDecl()))));
+ Nodify(Dst, D, Pred, SetValue(St, D, GetValue(St, D)));
}
void GRExprEngine::VisitCast(Expr* CastE, Expr* E, NodeTy* Pred, NodeSet& Dst) {
@@ -485,51 +484,29 @@
NodeTy* N1 = *I1;
StateTy St = N1->getState();
- switch (U->getOpcode()) {
- case UnaryOperator::PostInc: {
- const LValue& L1 = GetLValue(St, U->getSubExpr());
- NonLValue R1 = cast<NonLValue>(GetValue(St, L1));
-
- NonLValue Result = EvalBinaryOp(ValMgr, BinaryOperator::Add,
- R1, GetRValueConstant(1U, U));
-
- Nodify(Dst, U, N1, SetValue(SetValue(St, U, R1), L1, Result));
- break;
- }
-
- case UnaryOperator::PostDec: {
- const LValue& L1 = GetLValue(St, U->getSubExpr());
- NonLValue R1 = cast<NonLValue>(GetValue(St, L1));
-
- NonLValue Result = EvalBinaryOp(ValMgr, BinaryOperator::Sub,
- R1, GetRValueConstant(1U, U));
-
+ // Handle ++ and -- (both pre- and post-increment).
+
+ if (U->isIncrementDecrementOp()) {
+ const LValue& L1 = GetLValue(St, U->getSubExpr());
+ RValue R1 = GetValue(St, L1);
+
+ BinaryOperator::Opcode Op = U->isIncrementOp() ? BinaryOperator::Add
+ : BinaryOperator::Sub;
+
+ RValue Result = EvalBinaryOp(ValMgr, Op, R1, GetRValueConstant(1U, U));
+
+ if (U->isPostfix())
Nodify(Dst, U, N1, SetValue(SetValue(St, U, R1), L1, Result));
- break;
- }
-
- case UnaryOperator::PreInc: {
- const LValue& L1 = GetLValue(St, U->getSubExpr());
- NonLValue R1 = cast<NonLValue>(GetValue(St, L1));
-
- NonLValue Result = EvalBinaryOp(ValMgr, BinaryOperator::Add,
- R1, GetRValueConstant(1U, U));
-
+ else
Nodify(Dst, U, N1, SetValue(SetValue(St, U, Result), L1, Result));
- break;
- }
-
- case UnaryOperator::PreDec: {
- const LValue& L1 = GetLValue(St, U->getSubExpr());
- NonLValue R1 = cast<NonLValue>(GetValue(St, L1));
- NonLValue Result = EvalBinaryOp(ValMgr, BinaryOperator::Sub,
- R1, GetRValueConstant(1U, U));
+ continue;
+ }
+
+ // Handle all other unary operators.
+
+ switch (U->getOpcode()) {
- Nodify(Dst, U, N1, SetValue(SetValue(St, U, Result), L1, Result));
- break;
- }
-
case UnaryOperator::Minus: {
const NonLValue& R1 = cast<NonLValue>(GetValue(St, U->getSubExpr()));
Nodify(Dst, U, N1, SetValue(St, U, EvalMinus(ValMgr, U, R1)));
@@ -703,28 +680,7 @@
continue;
}
- if (isa<LValue>(V1)) {
- // FIXME: Add support for RHS being a non-lvalue.
- const LValue& L1 = cast<LValue>(V1);
-
- if (isa<LValue>(V2)) {
- const LValue& L2 = cast<LValue>(V2);
- Nodify(Dst, B, N2, SetValue(St, B,
- EvalBinaryOp(ValMgr, Op, L1, L2)));
- }
- else {
- const NonLValue& R2 = cast<NonLValue>(V2);
- Nodify(Dst, B, N2, SetValue(St, B,
- EvalBinaryOp(ValMgr, Op, L1, R2)));
- }
- }
- else {
- const NonLValue& R1 = cast<NonLValue>(V1);
- const NonLValue& R2 = cast<NonLValue>(V2);
-
- Nodify(Dst, B, N2, SetValue(St, B, EvalBinaryOp(ValMgr, Op, R1, R2)));
- }
-
+ Nodify(Dst, B, N2, SetValue(St, B, EvalBinaryOp(ValMgr, Op, V1, V2)));
continue;
}
@@ -746,14 +702,17 @@
if (Op >= BinaryOperator::AndAssign)
((int&) Op) -= (BinaryOperator::AndAssign - BinaryOperator::And);
else
- ((int&) Op) -= BinaryOperator::MulAssign;
+ ((int&) Op) -= BinaryOperator::MulAssign;
- if (isa<LValue>(V2)) {
- // FIXME: Add support for Non-LValues on RHS.
+ if (B->getType()->isPointerType()) { // Perform pointer arithmetic.
+ const NonLValue& R2 = cast<NonLValue>(V2);
+ Result = EvalBinaryOp(ValMgr, Op, L1, R2);
+ }
+ else if (isa<LValue>(V2)) { // LValue comparison.
const LValue& L2 = cast<LValue>(V2);
Result = EvalBinaryOp(ValMgr, Op, L1, L2);
}
- else {
+ else { // Any operation between two Non-LValues.
const NonLValue& R1 = cast<NonLValue>(GetValue(N1->getState(), L1));
const NonLValue& R2 = cast<NonLValue>(V2);
Result = EvalBinaryOp(ValMgr, Op, R1, R2);
Modified: cfe/trunk/Analysis/RValues.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/RValues.cpp?rev=47183&r1=47182&r2=47183&view=diff
==============================================================================
--- cfe/trunk/Analysis/RValues.cpp (original)
+++ cfe/trunk/Analysis/RValues.cpp Fri Feb 15 16:09:30 2008
@@ -428,11 +428,23 @@
}
static void printOpcode(std::ostream& Out, BinaryOperator::Opcode Op) {
- switch (Op) {
+ switch (Op) {
+ case BinaryOperator::Mul: Out << "*"; break;
+ case BinaryOperator::Div: Out << "/"; break;
+ case BinaryOperator::Rem: Out << "%" ; break;
case BinaryOperator::Add: Out << "+" ; break;
case BinaryOperator::Sub: Out << "-" ; break;
+ case BinaryOperator::Shl: Out << "<<" ; break;
+ case BinaryOperator::Shr: Out << ">>" ; break;
+ case BinaryOperator::LT: Out << "<" ; break;
+ case BinaryOperator::GT: Out << ">" ; break;
+ case BinaryOperator::LE: Out << "<=" ; break;
+ case BinaryOperator::GE: Out << ">=" ; break;
case BinaryOperator::EQ: Out << "=="; break;
case BinaryOperator::NE: Out << "!="; break;
+ case BinaryOperator::And: Out << "&" ; break;
+ case BinaryOperator::Xor: Out << "^" ; break;
+ case BinaryOperator::Or: Out << "|" ; break;
default: assert(false && "Not yet implemented.");
}
}
Modified: cfe/trunk/Analysis/ValueState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/ValueState.cpp?rev=47183&r1=47182&r2=47183&view=diff
==============================================================================
--- cfe/trunk/Analysis/ValueState.cpp (original)
+++ cfe/trunk/Analysis/ValueState.cpp Fri Feb 15 16:09:30 2008
@@ -91,7 +91,8 @@
Marked.insert(V);
if (V->getType()->isPointerType()) {
- const LValue& LV = cast<LValue>(GetValue(St, lval::DeclVal(V)));
+ const LValue& LV =
+ cast<LValue>(GetValue(St, lval::DeclVal(cast<VarDecl>(V))));
for (RValue::symbol_iterator SI=LV.symbol_begin(), SE=LV.symbol_end();
SI != SE; ++SI)
@@ -205,8 +206,25 @@
// context we assume that we are retrieving the value contained
// within the referenced variables.
- case Stmt::DeclRefExprClass:
- return GetValue(St, lval::DeclVal(cast<DeclRefExpr>(E)->getDecl()));
+ case Stmt::DeclRefExprClass: {
+ ValueDecl* D = cast<DeclRefExpr>(E)->getDecl();
+
+ if (VarDecl* VD = dyn_cast<VarDecl>(D))
+ return GetValue(St, lval::DeclVal(VD));
+ else if (EnumConstantDecl* ED = dyn_cast<EnumConstantDecl>(D)) {
+ // FIXME: Do we need to cache a copy of this enum, since it
+ // already has persistent storage? We do this because we
+ // are comparing states using pointer equality. Perhaps there is
+ // a better way, since APInts are fairly lightweight.
+ return nonlval::ConcreteInt(ValMgr.getValue(ED->getInitVal()));
+ }
+
+ assert (false &&
+ "ValueDecl support for this ValueDecl not implemented.");
+
+ return UnknownVal();
+ }
+
// Integer literals evaluate to an RValue. Simply retrieve the
// RValue for the literal.
@@ -278,7 +296,7 @@
E = P->getSubExpr();
if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(E))
- return lval::DeclVal(DR->getDecl());
+ return lval::DeclVal(cast<VarDecl>(DR->getDecl()));
if (UnaryOperator* U = dyn_cast<UnaryOperator>(E))
if (U->getOpcode() == UnaryOperator::Deref)
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h?rev=47183&r1=47182&r2=47183&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h Fri Feb 15 16:09:30 2008
@@ -203,7 +203,10 @@
friend class GRSwitchNodeBuilderImpl;
// Type definitions.
- typedef llvm::DenseMap<ProgramPoint,void*> EdgeNodeSetMap;
+ typedef llvm::DenseMap<ProgramPoint,
+ llvm::FoldingSet<clang::ExplodedNodeImpl>*>
+ EdgeNodeSetMap;
+
typedef llvm::SmallVector<ExplodedNodeImpl*,2> RootsTy;
typedef llvm::SmallVector<ExplodedNodeImpl*,10> EndNodesTy;
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=47183&r1=47182&r2=47183&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Fri Feb 15 16:09:30 2008
@@ -335,5 +335,10 @@
LValue LHS, NonLValue RHS) {
return TF->EvalBinaryOp(ValMgr, Op, LHS, RHS);
}
+
+ inline RValue EvalBinaryOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
+ RValue LHS, RValue RHS) {
+ return TF->EvalBinaryOp(ValMgr, Op, LHS, RHS);
+ }
};
} // end clang namespace
\ No newline at end of file
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h?rev=47183&r1=47182&r2=47183&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h Fri Feb 15 16:09:30 2008
@@ -47,12 +47,25 @@
BinaryOperator::Opcode Op,
LValue LHS, LValue RHS);
-
// Pointer arithmetic.
virtual LValue EvalBinaryOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
LValue LHS, NonLValue RHS) = 0;
+ inline RValue EvalBinaryOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
+ const RValue& L, const RValue& R) {
+
+ if (isa<LValue>(L)) {
+ if (isa<LValue>(R))
+ return EvalBinaryOp(ValMgr, Op, cast<LValue>(L), cast<LValue>(R));
+ else
+ return EvalBinaryOp(ValMgr, Op, cast<LValue>(L), cast<NonLValue>(R));
+ }
+ else
+ return EvalBinaryOp(ValMgr, Op, cast<NonLValue>(L), cast<NonLValue>(R));
+ }
+
+
// Equality operators for LValues.
virtual NonLValue EvalEQ(ValueManager& ValMgr, LValue LHS, LValue RHS) = 0;
virtual NonLValue EvalNE(ValueManager& ValMgr, LValue LHS, LValue RHS) = 0;
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/RValues.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/RValues.h?rev=47183&r1=47182&r2=47183&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/RValues.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/RValues.h Fri Feb 15 16:09:30 2008
@@ -474,10 +474,10 @@
class DeclVal : public LValue {
public:
- DeclVal(const ValueDecl* vd) : LValue(DeclValKind,vd) {}
+ DeclVal(const VarDecl* vd) : LValue(DeclValKind, vd) {}
- ValueDecl* getDecl() const {
- return static_cast<ValueDecl*>(Data);
+ VarDecl* getDecl() const {
+ return static_cast<VarDecl*>(Data);
}
inline bool operator==(const DeclVal& R) const {
More information about the cfe-commits
mailing list