diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Checker/ValueManager.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Checker/ValueManager.cpp | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/contrib/llvm/tools/clang/lib/Checker/ValueManager.cpp b/contrib/llvm/tools/clang/lib/Checker/ValueManager.cpp new file mode 100644 index 0000000..aa0c3c8 --- /dev/null +++ b/contrib/llvm/tools/clang/lib/Checker/ValueManager.cpp @@ -0,0 +1,149 @@ +//== ValueManager.cpp - Aggregate manager of symbols and SVals --*- C++ -*--==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines ValueManager, a class that manages symbolic values +// and SVals created for use by GRExprEngine and related classes. It +// wraps and owns SymbolManager, MemRegionManager, and BasicValueFactory. +// +//===----------------------------------------------------------------------===// + +#include "clang/Checker/PathSensitive/ValueManager.h" +#include "clang/Analysis/AnalysisContext.h" + +using namespace clang; +using namespace llvm; + +//===----------------------------------------------------------------------===// +// Utility methods for constructing SVals. +//===----------------------------------------------------------------------===// + +DefinedOrUnknownSVal ValueManager::makeZeroVal(QualType T) { + if (Loc::IsLocType(T)) + return makeNull(); + + if (T->isIntegerType()) + return makeIntVal(0, T); + + // FIXME: Handle floats. + // FIXME: Handle structs. + return UnknownVal(); +} + +//===----------------------------------------------------------------------===// +// Utility methods for constructing Non-Locs. +//===----------------------------------------------------------------------===// + +NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, + const APSInt& v, QualType T) { + // The Environment ensures we always get a persistent APSInt in + // BasicValueFactory, so we don't need to get the APSInt from + // BasicValueFactory again. + assert(!Loc::IsLocType(T)); + return nonloc::SymExprVal(SymMgr.getSymIntExpr(lhs, op, v, T)); +} + +NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, + const SymExpr *rhs, QualType T) { + assert(SymMgr.getType(lhs) == SymMgr.getType(rhs)); + assert(!Loc::IsLocType(T)); + return nonloc::SymExprVal(SymMgr.getSymSymExpr(lhs, op, rhs, T)); +} + + +SVal ValueManager::convertToArrayIndex(SVal V) { + if (V.isUnknownOrUndef()) + return V; + + // Common case: we have an appropriately sized integer. + if (nonloc::ConcreteInt* CI = dyn_cast<nonloc::ConcreteInt>(&V)) { + const llvm::APSInt& I = CI->getValue(); + if (I.getBitWidth() == ArrayIndexWidth && I.isSigned()) + return V; + } + + return SVator->EvalCastNL(cast<NonLoc>(V), ArrayIndexTy); +} + +DefinedOrUnknownSVal +ValueManager::getRegionValueSymbolVal(const TypedRegion* R) { + QualType T = R->getValueType(SymMgr.getContext()); + + if (!SymbolManager::canSymbolicate(T)) + return UnknownVal(); + + SymbolRef sym = SymMgr.getRegionValueSymbol(R); + + if (Loc::IsLocType(T)) + return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); + + return nonloc::SymbolVal(sym); +} + +DefinedOrUnknownSVal ValueManager::getConjuredSymbolVal(const void *SymbolTag, + const Expr *E, + unsigned Count) { + QualType T = E->getType(); + + if (!SymbolManager::canSymbolicate(T)) + return UnknownVal(); + + SymbolRef sym = SymMgr.getConjuredSymbol(E, Count, SymbolTag); + + if (Loc::IsLocType(T)) + return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); + + return nonloc::SymbolVal(sym); +} + +DefinedOrUnknownSVal ValueManager::getConjuredSymbolVal(const void *SymbolTag, + const Expr *E, + QualType T, + unsigned Count) { + + if (!SymbolManager::canSymbolicate(T)) + return UnknownVal(); + + SymbolRef sym = SymMgr.getConjuredSymbol(E, T, Count, SymbolTag); + + if (Loc::IsLocType(T)) + return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); + + return nonloc::SymbolVal(sym); +} + + +DefinedOrUnknownSVal +ValueManager::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, + const TypedRegion *R) { + QualType T = R->getValueType(R->getContext()); + + if (!SymbolManager::canSymbolicate(T)) + return UnknownVal(); + + SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, R); + + if (Loc::IsLocType(T)) + return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); + + return nonloc::SymbolVal(sym); +} + +DefinedSVal ValueManager::getFunctionPointer(const FunctionDecl* FD) { + return loc::MemRegionVal(MemMgr.getFunctionTextRegion(FD)); +} + +DefinedSVal ValueManager::getBlockPointer(const BlockDecl *D, + CanQualType locTy, + const LocationContext *LC) { + const BlockTextRegion *BC = + MemMgr.getBlockTextRegion(D, locTy, LC->getAnalysisContext()); + const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, LC); + return loc::MemRegionVal(BD); +} + |