1 //== ValueManager.cpp - Aggregate manager of symbols and SVals --*- C++ -*--==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines ValueManager, a class that manages symbolic values
11 // and SVals created for use by GRExprEngine and related classes. It
12 // wraps and owns SymbolManager, MemRegionManager, and BasicValueFactory.
14 //===----------------------------------------------------------------------===//
16 #include "clang/Checker/PathSensitive/ValueManager.h"
17 #include "clang/Analysis/AnalysisContext.h"
19 using namespace clang;
22 //===----------------------------------------------------------------------===//
23 // Utility methods for constructing SVals.
24 //===----------------------------------------------------------------------===//
26 DefinedOrUnknownSVal ValueManager::makeZeroVal(QualType T) {
27 if (Loc::IsLocType(T))
30 if (T->isIntegerType())
31 return makeIntVal(0, T);
33 // FIXME: Handle floats.
34 // FIXME: Handle structs.
38 //===----------------------------------------------------------------------===//
39 // Utility methods for constructing Non-Locs.
40 //===----------------------------------------------------------------------===//
42 NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
43 const APSInt& v, QualType T) {
44 // The Environment ensures we always get a persistent APSInt in
45 // BasicValueFactory, so we don't need to get the APSInt from
46 // BasicValueFactory again.
47 assert(!Loc::IsLocType(T));
48 return nonloc::SymExprVal(SymMgr.getSymIntExpr(lhs, op, v, T));
51 NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
52 const SymExpr *rhs, QualType T) {
53 assert(SymMgr.getType(lhs) == SymMgr.getType(rhs));
54 assert(!Loc::IsLocType(T));
55 return nonloc::SymExprVal(SymMgr.getSymSymExpr(lhs, op, rhs, T));
59 SVal ValueManager::convertToArrayIndex(SVal V) {
60 if (V.isUnknownOrUndef())
63 // Common case: we have an appropriately sized integer.
64 if (nonloc::ConcreteInt* CI = dyn_cast<nonloc::ConcreteInt>(&V)) {
65 const llvm::APSInt& I = CI->getValue();
66 if (I.getBitWidth() == ArrayIndexWidth && I.isSigned())
70 return SVator->EvalCastNL(cast<NonLoc>(V), ArrayIndexTy);
73 DefinedOrUnknownSVal ValueManager::getRegionValueSymbolVal(const MemRegion* R,
77 const TypedRegion* TR = cast<TypedRegion>(R);
78 T = TR->getValueType(SymMgr.getContext());
81 if (!SymbolManager::canSymbolicate(T))
84 SymbolRef sym = SymMgr.getRegionValueSymbol(R, T);
86 if (Loc::IsLocType(T))
87 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
89 return nonloc::SymbolVal(sym);
92 DefinedOrUnknownSVal ValueManager::getConjuredSymbolVal(const void *SymbolTag,
95 QualType T = E->getType();
97 if (!SymbolManager::canSymbolicate(T))
100 SymbolRef sym = SymMgr.getConjuredSymbol(E, Count, SymbolTag);
102 if (Loc::IsLocType(T))
103 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
105 return nonloc::SymbolVal(sym);
108 DefinedOrUnknownSVal ValueManager::getConjuredSymbolVal(const void *SymbolTag,
113 if (!SymbolManager::canSymbolicate(T))
116 SymbolRef sym = SymMgr.getConjuredSymbol(E, T, Count, SymbolTag);
118 if (Loc::IsLocType(T))
119 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
121 return nonloc::SymbolVal(sym);
126 ValueManager::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
127 const TypedRegion *R) {
128 QualType T = R->getValueType(R->getContext());
130 if (!SymbolManager::canSymbolicate(T))
133 SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, R);
135 if (Loc::IsLocType(T))
136 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
138 return nonloc::SymbolVal(sym);
141 DefinedSVal ValueManager::getFunctionPointer(const FunctionDecl* FD) {
142 return loc::MemRegionVal(MemMgr.getFunctionTextRegion(FD));
145 DefinedSVal ValueManager::getBlockPointer(const BlockDecl *D,
147 const LocationContext *LC) {
148 const BlockTextRegion *BC =
149 MemMgr.getBlockTextRegion(D, locTy, LC->getAnalysisContext());
150 const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, LC);
151 return loc::MemRegionVal(BD);