diff options
Diffstat (limited to 'clang/Analysis')
| -rw-r--r-- | clang/Analysis/RValues.cpp | 166 | ||||
| -rw-r--r-- | clang/Analysis/SymbolManager.cpp | 53 | ||||
| -rw-r--r-- | clang/Analysis/ValueManager.cpp | 134 |
3 files changed, 190 insertions, 163 deletions
diff --git a/clang/Analysis/RValues.cpp b/clang/Analysis/RValues.cpp index a9b44eb3d2a..c8a4dfa8d9a 100644 --- a/clang/Analysis/RValues.cpp +++ b/clang/Analysis/RValues.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "clang/Analysis/PathSensitive/RValues.h" +#include "llvm/Support/Streams.h" using namespace clang; using llvm::dyn_cast; @@ -20,110 +21,6 @@ using llvm::cast; using llvm::APSInt; //===----------------------------------------------------------------------===// -// SymbolManager. -//===----------------------------------------------------------------------===// - -SymbolID SymbolManager::getSymbol(ParmVarDecl* D) { - SymbolID& X = DataToSymbol[getKey(D)]; - - if (!X.isInitialized()) { - X = SymbolToData.size(); - SymbolToData.push_back(SymbolDataParmVar(D)); - } - - return X; -} - -SymbolID SymbolManager::getContentsOfSymbol(SymbolID sym) { - SymbolID& X = DataToSymbol[getKey(sym)]; - - if (!X.isInitialized()) { - X = SymbolToData.size(); - SymbolToData.push_back(SymbolDataContentsOf(sym)); - } - - return X; -} - -QualType SymbolData::getType() const { - switch (getKind()) { - default: - assert (false && "getType() not implemented for this symbol."); - - case ParmKind: - return cast<SymbolDataParmVar>(this)->getDecl()->getType(); - - } -} - -SymbolManager::SymbolManager() {} -SymbolManager::~SymbolManager() {} - -//===----------------------------------------------------------------------===// -// Values and ValueManager. -//===----------------------------------------------------------------------===// - -ValueManager::~ValueManager() { - // Note that the dstor for the contents of APSIntSet will never be called, - // so we iterate over the set and invoke the dstor for each APSInt. This - // frees an aux. memory allocated to represent very large constants. - for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I) - I->getValue().~APSInt(); -} - -const APSInt& ValueManager::getValue(const APSInt& X) { - llvm::FoldingSetNodeID ID; - void* InsertPos; - typedef llvm::FoldingSetNodeWrapper<APSInt> FoldNodeTy; - - X.Profile(ID); - FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos); - - if (!P) { - P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>(); - new (P) FoldNodeTy(X); - APSIntSet.InsertNode(P, InsertPos); - } - - return *P; -} - -const APSInt& ValueManager::getValue(uint64_t X, unsigned BitWidth, - bool isUnsigned) { - APSInt V(BitWidth, isUnsigned); - V = X; - return getValue(V); -} - -const APSInt& ValueManager::getValue(uint64_t X, QualType T, - SourceLocation Loc) { - - unsigned bits = Ctx.getTypeSize(T, Loc); - APSInt V(bits, T->isUnsignedIntegerType()); - V = X; - return getValue(V); -} - -const SymIntConstraint& -ValueManager::getConstraint(SymbolID sym, BinaryOperator::Opcode Op, - const llvm::APSInt& V) { - - llvm::FoldingSetNodeID ID; - SymIntConstraint::Profile(ID, sym, Op, V); - void* InsertPos; - - SymIntConstraint* C = SymIntCSet.FindNodeOrInsertPos(ID, InsertPos); - - if (!C) { - C = (SymIntConstraint*) BPAlloc.Allocate<SymIntConstraint>(); - new (C) SymIntConstraint(sym, Op, V); - SymIntCSet.InsertNode(C, InsertPos); - } - - return *C; -} - -//===----------------------------------------------------------------------===// // Symbol Iteration. //===----------------------------------------------------------------------===// @@ -154,69 +51,12 @@ RValue::symbol_iterator RValue::symbol_end() const { // Transfer function dispatch for Non-LValues. //===----------------------------------------------------------------------===// -static const -llvm::APSInt& EvaluateAPSInt(ValueManager& ValMgr, BinaryOperator::Opcode Op, - const llvm::APSInt& V1, const llvm::APSInt& V2) { - - switch (Op) { - default: - assert (false && "Invalid Opcode."); - - case BinaryOperator::Mul: - return ValMgr.getValue( V1 * V2 ); - - case BinaryOperator::Div: - return ValMgr.getValue( V1 / V2 ); - - case BinaryOperator::Rem: - return ValMgr.getValue( V1 % V2 ); - - case BinaryOperator::Add: - return ValMgr.getValue( V1 + V2 ); - - case BinaryOperator::Sub: - return ValMgr.getValue( V1 - V2 ); - - case BinaryOperator::Shl: - return ValMgr.getValue( V1.operator<<( (unsigned) V2.getZExtValue() )); - - case BinaryOperator::Shr: - return ValMgr.getValue( V1.operator>>( (unsigned) V2.getZExtValue() )); - - case BinaryOperator::LT: - return ValMgr.getTruthValue( V1 < V2 ); - - case BinaryOperator::GT: - return ValMgr.getTruthValue( V1 > V2 ); - - case BinaryOperator::LE: - return ValMgr.getTruthValue( V1 <= V2 ); - - case BinaryOperator::GE: - return ValMgr.getTruthValue( V1 >= V2 ); - - case BinaryOperator::EQ: - return ValMgr.getTruthValue( V1 == V2 ); - - case BinaryOperator::NE: - return ValMgr.getTruthValue( V1 != V2 ); - - // Note: LAnd, LOr, Comma are handled specially by higher-level logic. - - case BinaryOperator::And: - return ValMgr.getValue( V1 & V2 ); - - case BinaryOperator::Or: - return ValMgr.getValue( V1 | V2 ); - } -} - nonlval::ConcreteInt nonlval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr, BinaryOperator::Opcode Op, const nonlval::ConcreteInt& RHS) const { - return EvaluateAPSInt(ValMgr, Op, getValue(), RHS.getValue()); + return ValMgr.EvaluateAPSInt(Op, getValue(), RHS.getValue()); } @@ -249,7 +89,7 @@ lval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr, assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub || (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE)); - return EvaluateAPSInt(ValMgr, Op, getValue(), RHS.getValue()); + return ValMgr.EvaluateAPSInt(Op, getValue(), RHS.getValue()); } NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const { diff --git a/clang/Analysis/SymbolManager.cpp b/clang/Analysis/SymbolManager.cpp new file mode 100644 index 00000000000..bdda0e6eed3 --- /dev/null +++ b/clang/Analysis/SymbolManager.cpp @@ -0,0 +1,53 @@ +//== SymbolManager.h - Management of Symbolic 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 SymbolManager, a class that manages symbolic values +// created for use by GRExprEngine and related classes. +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/PathSensitive/SymbolManager.h" + +using namespace clang; + +SymbolID SymbolManager::getSymbol(ParmVarDecl* D) { + SymbolID& X = DataToSymbol[getKey(D)]; + + if (!X.isInitialized()) { + X = SymbolToData.size(); + SymbolToData.push_back(SymbolDataParmVar(D)); + } + + return X; +} + +SymbolID SymbolManager::getContentsOfSymbol(SymbolID sym) { + SymbolID& X = DataToSymbol[getKey(sym)]; + + if (!X.isInitialized()) { + X = SymbolToData.size(); + SymbolToData.push_back(SymbolDataContentsOf(sym)); + } + + return X; +} + +QualType SymbolData::getType() const { + switch (getKind()) { + default: + assert (false && "getType() not implemented for this symbol."); + + case ParmKind: + return cast<SymbolDataParmVar>(this)->getDecl()->getType(); + + } +} + +SymbolManager::SymbolManager() {} +SymbolManager::~SymbolManager() {} diff --git a/clang/Analysis/ValueManager.cpp b/clang/Analysis/ValueManager.cpp new file mode 100644 index 00000000000..61a2154c342 --- /dev/null +++ b/clang/Analysis/ValueManager.cpp @@ -0,0 +1,134 @@ +// ValueManager.h - Low-level value management for Value Tracking -*- 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 ValueManager, a class that manages the lifetime of APSInt +// objects and symbolic constraints used by GRExprEngine and related classes. +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/PathSensitive/ValueManager.h" + +using namespace clang; + +ValueManager::~ValueManager() { + // Note that the dstor for the contents of APSIntSet will never be called, + // so we iterate over the set and invoke the dstor for each APSInt. This + // frees an aux. memory allocated to represent very large constants. + for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I) + I->getValue().~APSInt(); +} + +const llvm::APSInt& ValueManager::getValue(const llvm::APSInt& X) { + llvm::FoldingSetNodeID ID; + void* InsertPos; + typedef llvm::FoldingSetNodeWrapper<llvm::APSInt> FoldNodeTy; + + X.Profile(ID); + FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos); + + if (!P) { + P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>(); + new (P) FoldNodeTy(X); + APSIntSet.InsertNode(P, InsertPos); + } + + return *P; +} + +const llvm::APSInt& ValueManager::getValue(uint64_t X, unsigned BitWidth, + bool isUnsigned) { + llvm::APSInt V(BitWidth, isUnsigned); + V = X; + return getValue(V); +} + +const llvm::APSInt& ValueManager::getValue(uint64_t X, QualType T, + SourceLocation Loc) { + + unsigned bits = Ctx.getTypeSize(T, Loc); + llvm::APSInt V(bits, T->isUnsignedIntegerType()); + V = X; + return getValue(V); +} + +const SymIntConstraint& +ValueManager::getConstraint(SymbolID sym, BinaryOperator::Opcode Op, + const llvm::APSInt& V) { + + llvm::FoldingSetNodeID ID; + SymIntConstraint::Profile(ID, sym, Op, V); + void* InsertPos; + + SymIntConstraint* C = SymIntCSet.FindNodeOrInsertPos(ID, InsertPos); + + if (!C) { + C = (SymIntConstraint*) BPAlloc.Allocate<SymIntConstraint>(); + new (C) SymIntConstraint(sym, Op, V); + SymIntCSet.InsertNode(C, InsertPos); + } + + return *C; +} + +const llvm::APSInt& +ValueManager::EvaluateAPSInt(BinaryOperator::Opcode Op, + const llvm::APSInt& V1, const llvm::APSInt& V2) { + + switch (Op) { + default: + assert (false && "Invalid Opcode."); + + case BinaryOperator::Mul: + return getValue( V1 * V2 ); + + case BinaryOperator::Div: + return getValue( V1 / V2 ); + + case BinaryOperator::Rem: + return getValue( V1 % V2 ); + + case BinaryOperator::Add: + return getValue( V1 + V2 ); + + case BinaryOperator::Sub: + return getValue( V1 - V2 ); + + case BinaryOperator::Shl: + return getValue( V1.operator<<( (unsigned) V2.getZExtValue() )); + + case BinaryOperator::Shr: + return getValue( V1.operator>>( (unsigned) V2.getZExtValue() )); + + case BinaryOperator::LT: + return getTruthValue( V1 < V2 ); + + case BinaryOperator::GT: + return getTruthValue( V1 > V2 ); + + case BinaryOperator::LE: + return getTruthValue( V1 <= V2 ); + + case BinaryOperator::GE: + return getTruthValue( V1 >= V2 ); + + case BinaryOperator::EQ: + return getTruthValue( V1 == V2 ); + + case BinaryOperator::NE: + return getTruthValue( V1 != V2 ); + + // Note: LAnd, LOr, Comma are handled specially by higher-level logic. + + case BinaryOperator::And: + return getValue( V1 & V2 ); + + case BinaryOperator::Or: + return getValue( V1 | V2 ); + } +} |

