blob: 0f345602a22dd2f13910eb0623ad75afaf5db1f3 [file] [log] [blame]
Ted Kremeneka90ccfe2008-01-31 19:34:24 +00001//= RValues.cpp - Abstract RValues for Path-Sens. Value Tracking -*- C++ -*-==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Zhongxing Xu1c96b242008-10-17 05:57:07 +000010// This file defines SVal, Loc, and NonLoc, classes that represent
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000011// abstract r-values for use with path-sensitive value tracking.
12//
13//===----------------------------------------------------------------------===//
14
Ted Kremenek9e240492008-10-04 05:50:14 +000015#include "clang/Analysis/PathSensitive/GRState.h"
Daniel Dunbarc4a1dea2008-08-11 05:35:13 +000016#include "clang/Basic/IdentifierTable.h"
Ted Kremenekd70d0b02008-02-16 01:12:31 +000017#include "llvm/Support/Streams.h"
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000018
19using namespace clang;
20using llvm::dyn_cast;
21using llvm::cast;
22using llvm::APSInt;
23
24//===----------------------------------------------------------------------===//
Ted Kremenek90e14812008-02-14 23:25:54 +000025// Symbol Iteration.
26//===----------------------------------------------------------------------===//
Ted Kremeneka6e4d212008-02-01 06:36:40 +000027
Zhongxing Xu1c96b242008-10-17 05:57:07 +000028SVal::symbol_iterator SVal::symbol_begin() const {
Ted Kremenek718c4f72008-04-29 22:17:41 +000029 // FIXME: This is a rat's nest. Cleanup.
30
Zhongxing Xu1c96b242008-10-17 05:57:07 +000031 if (isa<loc::SymbolVal>(this))
Ted Kremenek2dabd432008-12-05 02:27:51 +000032 return symbol_iterator(SymbolRef((uintptr_t)Data));
Zhongxing Xu1c96b242008-10-17 05:57:07 +000033 else if (isa<nonloc::SymbolVal>(this))
Ted Kremenek2dabd432008-12-05 02:27:51 +000034 return symbol_iterator(SymbolRef((uintptr_t)Data));
Zhongxing Xu1c96b242008-10-17 05:57:07 +000035 else if (isa<nonloc::SymIntConstraintVal>(this)) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000036 const SymIntConstraint& C =
Ted Kremenek0d958e72008-10-27 23:39:39 +000037 cast<nonloc::SymIntConstraintVal>(this)->getConstraint();
38 return symbol_iterator(C.getSymbol());
Ted Kremenek90e14812008-02-14 23:25:54 +000039 }
Zhongxing Xu1c96b242008-10-17 05:57:07 +000040 else if (isa<nonloc::LocAsInteger>(this)) {
41 const nonloc::LocAsInteger& V = cast<nonloc::LocAsInteger>(*this);
42 return V.getPersistentLoc().symbol_begin();
Ted Kremenek0fe33bc2008-04-22 21:10:18 +000043 }
Ted Kremenek0d958e72008-10-27 23:39:39 +000044 else if (isa<loc::MemRegionVal>(this)) {
45 const MemRegion* R = cast<loc::MemRegionVal>(this)->getRegion();
46 if (const SymbolicRegion* S = dyn_cast<SymbolicRegion>(R))
47 return symbol_iterator(S->getSymbol());
48 }
Ted Kremenekd9bc33e2008-10-17 00:51:01 +000049
Ted Kremenek0d958e72008-10-27 23:39:39 +000050 return symbol_iterator();
Ted Kremenek90e14812008-02-14 23:25:54 +000051}
52
Zhongxing Xu1c96b242008-10-17 05:57:07 +000053SVal::symbol_iterator SVal::symbol_end() const {
Ted Kremenek0d958e72008-10-27 23:39:39 +000054 return symbol_iterator();
Ted Kremenek90e14812008-02-14 23:25:54 +000055}
Ted Kremeneka6e4d212008-02-01 06:36:40 +000056
Ted Kremenek94c96982009-03-03 22:06:47 +000057/// getAsLocSymbol - If this SVal is a location (subclasses Loc) and
58/// wraps a symbol, return that SymbolRef. Otherwise return a SymbolRef
59/// where 'isValid()' returns false.
60SymbolRef SVal::getAsLocSymbol() const {
61 if (const loc::SymbolVal *X = dyn_cast<loc::SymbolVal>(this))
62 return X->getSymbol();
63
64 if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this)) {
65 const MemRegion *R = X->getRegion();
66
67 while (R) {
68 // Blast through region views.
69 if (const TypedViewRegion *View = dyn_cast<TypedViewRegion>(R)) {
70 R = View->getSuperRegion();
71 continue;
72 }
73
74 if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
75 return SymR->getSymbol();
76
77 break;
78 }
79 }
80
81 return SymbolRef();
82}
83
84/// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
85/// Otherwise return a SymbolRef where 'isValid()' returns false.
86SymbolRef SVal::getAsSymbol() const {
87 if (const nonloc::SymbolVal *X = dyn_cast<nonloc::SymbolVal>(this))
88 return X->getSymbol();
89
90 return getAsLocSymbol();
91}
92
Ted Kremenekcf78b6a2008-02-06 22:50:25 +000093//===----------------------------------------------------------------------===//
Ted Kremeneka6fac4e2008-10-30 18:01:28 +000094// Other Iterators.
95//===----------------------------------------------------------------------===//
96
97nonloc::CompoundVal::iterator nonloc::CompoundVal::begin() const {
98 return getValue()->begin();
99}
100
101nonloc::CompoundVal::iterator nonloc::CompoundVal::end() const {
102 return getValue()->end();
103}
104
105//===----------------------------------------------------------------------===//
Ted Kremenek40fc5c72008-07-18 15:54:51 +0000106// Useful predicates.
107//===----------------------------------------------------------------------===//
108
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000109bool SVal::isZeroConstant() const {
110 if (isa<loc::ConcreteInt>(*this))
111 return cast<loc::ConcreteInt>(*this).getValue() == 0;
112 else if (isa<nonloc::ConcreteInt>(*this))
113 return cast<nonloc::ConcreteInt>(*this).getValue() == 0;
Ted Kremenek40fc5c72008-07-18 15:54:51 +0000114 else
115 return false;
116}
117
118
119//===----------------------------------------------------------------------===//
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000120// Transfer function dispatch for Non-Locs.
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000121//===----------------------------------------------------------------------===//
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000122
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000123SVal nonloc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals,
Ted Kremenek75b0a1c2008-07-18 15:59:33 +0000124 BinaryOperator::Opcode Op,
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000125 const nonloc::ConcreteInt& R) const {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000126
Ted Kremenek75b0a1c2008-07-18 15:59:33 +0000127 const llvm::APSInt* X =
128 BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue());
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000129
130 if (X)
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000131 return nonloc::ConcreteInt(*X);
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000132 else
133 return UndefinedVal();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000134}
135
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000136 // Bitwise-Complement.
137
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000138nonloc::ConcreteInt
139nonloc::ConcreteInt::EvalComplement(BasicValueFactory& BasicVals) const {
Ted Kremenek240f1f02008-03-07 20:13:31 +0000140 return BasicVals.getValue(~getValue());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000141}
142
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000143 // Unary Minus.
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000144
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000145nonloc::ConcreteInt
146nonloc::ConcreteInt::EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const {
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000147 assert (U->getType() == U->getSubExpr()->getType());
148 assert (U->getType()->isIntegerType());
Ted Kremenek240f1f02008-03-07 20:13:31 +0000149 return BasicVals.getValue(-getValue());
Ted Kremenekc5d3b4c2008-02-04 16:58:30 +0000150}
151
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000152//===----------------------------------------------------------------------===//
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000153// Transfer function dispatch for Locs.
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000154//===----------------------------------------------------------------------===//
155
Ted Kremenekccaad9d2008-10-30 17:53:23 +0000156SVal loc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals,
157 BinaryOperator::Opcode Op,
158 const loc::ConcreteInt& R) const {
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000159
160 assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub ||
161 (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE));
162
Ted Kremenek240f1f02008-03-07 20:13:31 +0000163 const llvm::APSInt* X = BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue());
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000164
165 if (X)
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000166 return loc::ConcreteInt(*X);
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000167 else
168 return UndefinedVal();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000169}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000170
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000171NonLoc Loc::EQ(BasicValueFactory& BasicVals, const Loc& R) const {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000172
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000173 switch (getSubKind()) {
174 default:
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000175 assert(false && "EQ not implemented for this Loc.");
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000176 break;
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000177
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000178 case loc::ConcreteIntKind:
179 if (isa<loc::ConcreteInt>(R)) {
180 bool b = cast<loc::ConcreteInt>(this)->getValue() ==
181 cast<loc::ConcreteInt>(R).getValue();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000182
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000183 return NonLoc::MakeIntTruthVal(BasicVals, b);
Ted Kremenek0806acf2008-02-05 23:08:41 +0000184 }
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000185 else if (isa<loc::SymbolVal>(R)) {
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000186
Ted Kremenek0806acf2008-02-05 23:08:41 +0000187 const SymIntConstraint& C =
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000188 BasicVals.getConstraint(cast<loc::SymbolVal>(R).getSymbol(),
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000189 BinaryOperator::EQ,
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000190 cast<loc::ConcreteInt>(this)->getValue());
Ted Kremenek0806acf2008-02-05 23:08:41 +0000191
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000192 return nonloc::SymIntConstraintVal(C);
Ted Kremenek0806acf2008-02-05 23:08:41 +0000193 }
194
195 break;
196
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000197 case loc::SymbolValKind: {
198 if (isa<loc::ConcreteInt>(R)) {
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000199
200 const SymIntConstraint& C =
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000201 BasicVals.getConstraint(cast<loc::SymbolVal>(this)->getSymbol(),
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000202 BinaryOperator::EQ,
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000203 cast<loc::ConcreteInt>(R).getValue());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000204
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000205 return nonloc::SymIntConstraintVal(C);
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000206 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000207
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000208 assert (!isa<loc::SymbolVal>(R) && "FIXME: Implement unification.");
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000209
210 break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000211 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000212
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000213 case loc::MemRegionKind:
214 if (isa<loc::MemRegionVal>(R)) {
215 bool b = cast<loc::MemRegionVal>(*this) == cast<loc::MemRegionVal>(R);
216 return NonLoc::MakeIntTruthVal(BasicVals, b);
Ted Kremenek0806acf2008-02-05 23:08:41 +0000217 }
218
219 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000220 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000221
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000222 return NonLoc::MakeIntTruthVal(BasicVals, false);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000223}
224
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000225NonLoc Loc::NE(BasicValueFactory& BasicVals, const Loc& R) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000226 switch (getSubKind()) {
227 default:
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000228 assert(false && "NE not implemented for this Loc.");
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000229 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000230
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000231 case loc::ConcreteIntKind:
232 if (isa<loc::ConcreteInt>(R)) {
233 bool b = cast<loc::ConcreteInt>(this)->getValue() !=
234 cast<loc::ConcreteInt>(R).getValue();
Ted Kremenek0806acf2008-02-05 23:08:41 +0000235
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000236 return NonLoc::MakeIntTruthVal(BasicVals, b);
Ted Kremenek0806acf2008-02-05 23:08:41 +0000237 }
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000238 else if (isa<loc::SymbolVal>(R)) {
Ted Kremenek0806acf2008-02-05 23:08:41 +0000239
240 const SymIntConstraint& C =
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000241 BasicVals.getConstraint(cast<loc::SymbolVal>(R).getSymbol(),
Ted Kremenek0806acf2008-02-05 23:08:41 +0000242 BinaryOperator::NE,
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000243 cast<loc::ConcreteInt>(this)->getValue());
Ted Kremenek0806acf2008-02-05 23:08:41 +0000244
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000245 return nonloc::SymIntConstraintVal(C);
Ted Kremenek0806acf2008-02-05 23:08:41 +0000246 }
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000247
Ted Kremenek0806acf2008-02-05 23:08:41 +0000248 break;
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000249
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000250 case loc::SymbolValKind: {
251 if (isa<loc::ConcreteInt>(R)) {
Ted Kremenek0806acf2008-02-05 23:08:41 +0000252
253 const SymIntConstraint& C =
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000254 BasicVals.getConstraint(cast<loc::SymbolVal>(this)->getSymbol(),
Ted Kremenek0806acf2008-02-05 23:08:41 +0000255 BinaryOperator::NE,
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000256 cast<loc::ConcreteInt>(R).getValue());
Ted Kremenek0806acf2008-02-05 23:08:41 +0000257
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000258 return nonloc::SymIntConstraintVal(C);
Ted Kremenek0806acf2008-02-05 23:08:41 +0000259 }
260
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000261 assert (!isa<loc::SymbolVal>(R) && "FIXME: Implement sym !=.");
Ted Kremenek0806acf2008-02-05 23:08:41 +0000262
263 break;
264 }
265
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000266 case loc::MemRegionKind:
267 if (isa<loc::MemRegionVal>(R)) {
268 bool b = cast<loc::MemRegionVal>(*this)==cast<loc::MemRegionVal>(R);
269 return NonLoc::MakeIntTruthVal(BasicVals, b);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000270 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000271
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000272 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000273 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000274
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000275 return NonLoc::MakeIntTruthVal(BasicVals, true);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000276}
277
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000278//===----------------------------------------------------------------------===//
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000279// Utility methods for constructing Non-Locs.
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000280//===----------------------------------------------------------------------===//
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000281
282NonLoc NonLoc::MakeVal(SymbolRef sym) {
283 return nonloc::SymbolVal(sym);
284}
285
Zhongxing Xua129eb92009-03-25 05:58:37 +0000286NonLoc NonLoc::MakeVal(SymbolManager& SymMgr, SymbolRef lhs,
287 BinaryOperator::Opcode op, const APSInt& v) {
288 // The Environment ensures we always get a persistent APSInt in
289 // BasicValueFactory, so we don't need to get the APSInt from
290 // BasicValueFactory again.
291
292 SymbolRef sym = SymMgr.getSymIntExpr(lhs, op, v, SymMgr.getType(lhs));
293 return nonloc::SymbolVal(sym);
294}
295
296NonLoc NonLoc::MakeVal(SymbolManager& SymMgr, SymbolRef lhs,
297 BinaryOperator::Opcode op, SymbolRef rhs) {
298 assert(SymMgr.getType(lhs) == SymMgr.getType(rhs));
299 SymbolRef sym = SymMgr.getSymSymExpr(lhs, op, rhs, SymMgr.getType(lhs));
300 return nonloc::SymbolVal(sym);
301}
302
Ted Kremenek14553ab2009-01-30 00:08:43 +0000303NonLoc NonLoc::MakeIntVal(BasicValueFactory& BasicVals, uint64_t X,
304 bool isUnsigned) {
305 return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned));
Zhongxing Xu6613d082008-11-24 02:18:56 +0000306}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000307
Zhongxing Xu8b862732008-11-24 09:38:21 +0000308NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, uint64_t X,
309 unsigned BitWidth, bool isUnsigned) {
310 return nonloc::ConcreteInt(BasicVals.getValue(X, BitWidth, isUnsigned));
311}
312
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000313NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T) {
314 return nonloc::ConcreteInt(BasicVals.getValue(X, T));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000315}
316
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000317NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000318
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000319 return nonloc::ConcreteInt(BasicVals.getValue(APSInt(I->getValue(),
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000320 I->getType()->isUnsignedIntegerType())));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000321}
322
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000323NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, const llvm::APInt& I,
324 bool isUnsigned) {
325 return nonloc::ConcreteInt(BasicVals.getValue(I, isUnsigned));
326}
327
Zhongxing Xu8b862732008-11-24 09:38:21 +0000328NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, const llvm::APSInt& I) {
329 return nonloc::ConcreteInt(BasicVals.getValue(I));
330}
331
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000332NonLoc NonLoc::MakeIntTruthVal(BasicValueFactory& BasicVals, bool b) {
333 return nonloc::ConcreteInt(BasicVals.getTruthValue(b));
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000334}
335
Ted Kremenek632e8b82008-10-30 17:44:46 +0000336NonLoc NonLoc::MakeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals,
Zhongxing Xu6764b722008-10-30 04:58:00 +0000337 BasicValueFactory& BasicVals) {
Ted Kremenek632e8b82008-10-30 17:44:46 +0000338 return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
Zhongxing Xu6764b722008-10-30 04:58:00 +0000339}
340
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000341SVal SVal::GetRValueSymbolVal(SymbolManager& SymMgr, const MemRegion* R) {
342 SymbolRef sym = SymMgr.getRegionRValueSymbol(R);
343
Ted Kremenekec099f12009-03-18 22:10:22 +0000344 if (const TypedRegion* TR = dyn_cast<TypedRegion>(R)) {
345 QualType T = TR->getRValueType(SymMgr.getContext());
346
347 if (Loc::IsLocType(T))
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000348 return Loc::MakeVal(sym);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000349
Ted Kremenekec099f12009-03-18 22:10:22 +0000350 // Only handle integers for now.
351 if (T->isIntegerType())
352 return NonLoc::MakeVal(sym);
353 }
354
355 return UnknownVal();
Zhongxing Xueabf7762008-11-19 11:03:17 +0000356}
357
Ted Kremenekbb9b2712009-03-20 20:10:45 +0000358SVal SVal::GetConjuredSymbolVal(SymbolManager &SymMgr, const Expr* E,
359 unsigned Count) {
360
361 QualType T = E->getType();
362
363 if (Loc::IsLocType(T)) {
364 SymbolRef Sym = SymMgr.getConjuredSymbol(E, Count);
365 return loc::SymbolVal(Sym);
366 }
367 else if (T->isIntegerType() && T->isScalarType()) {
368 SymbolRef Sym = SymMgr.getConjuredSymbol(E, Count);
369 return nonloc::SymbolVal(Sym);
370 }
371
372 return UnknownVal();
373}
374
Ted Kremenek632e8b82008-10-30 17:44:46 +0000375nonloc::LocAsInteger nonloc::LocAsInteger::Make(BasicValueFactory& Vals, Loc V,
376 unsigned Bits) {
377 return LocAsInteger(Vals.getPersistentSValWithData(V, Bits));
378}
379
Ted Kremenek2a502572008-02-12 21:37:56 +0000380//===----------------------------------------------------------------------===//
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000381// Utility methods for constructing Locs.
Ted Kremenek2a502572008-02-12 21:37:56 +0000382//===----------------------------------------------------------------------===//
383
Zhongxing Xu2fdf5552008-12-09 10:51:19 +0000384Loc Loc::MakeVal(const MemRegion* R) { return loc::MemRegionVal(R); }
385
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000386Loc Loc::MakeVal(AddrLabelExpr* E) { return loc::GotoLabel(E->getLabel()); }
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000387
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000388Loc Loc::MakeVal(SymbolRef sym) { return loc::SymbolVal(sym); }
389
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000390//===----------------------------------------------------------------------===//
391// Pretty-Printing.
392//===----------------------------------------------------------------------===//
393
Daniel Dunbar4a77edb2009-03-10 18:00:19 +0000394void SVal::printStdErr() const { print(llvm::errs()); }
Ted Kremenek2a502572008-02-12 21:37:56 +0000395
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000396void SVal::print(std::ostream& Out) const {
Ted Kremenekb8b41612008-10-30 18:35:10 +0000397 llvm::raw_os_ostream out(Out);
398 print(out);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000399}
400
Zhongxing Xu9012bff2008-10-24 06:00:12 +0000401void SVal::print(llvm::raw_ostream& Out) const {
402
403 switch (getBaseKind()) {
404
405 case UnknownKind:
406 Out << "Invalid"; break;
407
408 case NonLocKind:
409 cast<NonLoc>(this)->print(Out); break;
410
411 case LocKind:
412 cast<Loc>(this)->print(Out); break;
413
414 case UndefinedKind:
415 Out << "Undefined"; break;
416
417 default:
418 assert (false && "Invalid SVal.");
419 }
420}
421
422static void printOpcode(llvm::raw_ostream& Out, BinaryOperator::Opcode Op) {
423
424 switch (Op) {
425 case BinaryOperator::Mul: Out << '*' ; break;
426 case BinaryOperator::Div: Out << '/' ; break;
427 case BinaryOperator::Rem: Out << '%' ; break;
428 case BinaryOperator::Add: Out << '+' ; break;
429 case BinaryOperator::Sub: Out << '-' ; break;
430 case BinaryOperator::Shl: Out << "<<" ; break;
431 case BinaryOperator::Shr: Out << ">>" ; break;
432 case BinaryOperator::LT: Out << "<" ; break;
433 case BinaryOperator::GT: Out << '>' ; break;
434 case BinaryOperator::LE: Out << "<=" ; break;
435 case BinaryOperator::GE: Out << ">=" ; break;
436 case BinaryOperator::EQ: Out << "==" ; break;
437 case BinaryOperator::NE: Out << "!=" ; break;
438 case BinaryOperator::And: Out << '&' ; break;
439 case BinaryOperator::Xor: Out << '^' ; break;
440 case BinaryOperator::Or: Out << '|' ; break;
441
442 default: assert(false && "Not yet implemented.");
443 }
444}
445
446void NonLoc::print(llvm::raw_ostream& Out) const {
447
448 switch (getSubKind()) {
449
450 case nonloc::ConcreteIntKind:
451 Out << cast<nonloc::ConcreteInt>(this)->getValue().getZExtValue();
452
453 if (cast<nonloc::ConcreteInt>(this)->getValue().isUnsigned())
454 Out << 'U';
455
456 break;
457
458 case nonloc::SymbolValKind:
459 Out << '$' << cast<nonloc::SymbolVal>(this)->getSymbol();
460 break;
461
462 case nonloc::SymIntConstraintValKind: {
463 const nonloc::SymIntConstraintVal& C =
464 *cast<nonloc::SymIntConstraintVal>(this);
465
466 Out << '$' << C.getConstraint().getSymbol() << ' ';
467 printOpcode(Out, C.getConstraint().getOpcode());
468 Out << ' ' << C.getConstraint().getInt().getZExtValue();
469
470 if (C.getConstraint().getInt().isUnsigned())
471 Out << 'U';
472
473 break;
474 }
475
476 case nonloc::LocAsIntegerKind: {
477 const nonloc::LocAsInteger& C = *cast<nonloc::LocAsInteger>(this);
478 C.getLoc().print(Out);
479 Out << " [as " << C.getNumBits() << " bit integer]";
480 break;
481 }
482
Ted Kremeneka6fac4e2008-10-30 18:01:28 +0000483 case nonloc::CompoundValKind: {
484 const nonloc::CompoundVal& C = *cast<nonloc::CompoundVal>(this);
Ted Kremenekb8b41612008-10-30 18:35:10 +0000485 Out << " {";
486 bool first = true;
487 for (nonloc::CompoundVal::iterator I=C.begin(), E=C.end(); I!=E; ++I) {
488 if (first) { Out << ' '; first = false; }
489 else Out << ", ";
Ted Kremeneka6fac4e2008-10-30 18:01:28 +0000490 (*I).print(Out);
Ted Kremenekb8b41612008-10-30 18:35:10 +0000491 }
Ted Kremeneka6fac4e2008-10-30 18:01:28 +0000492 Out << " }";
493 break;
494 }
495
Zhongxing Xu9012bff2008-10-24 06:00:12 +0000496 default:
497 assert (false && "Pretty-printed not implemented for this NonLoc.");
498 break;
499 }
500}
501
502void Loc::print(llvm::raw_ostream& Out) const {
503
504 switch (getSubKind()) {
505
506 case loc::ConcreteIntKind:
507 Out << cast<loc::ConcreteInt>(this)->getValue().getZExtValue()
508 << " (Loc)";
509 break;
510
511 case loc::SymbolValKind:
512 Out << '$' << cast<loc::SymbolVal>(this)->getSymbol();
513 break;
514
515 case loc::GotoLabelKind:
516 Out << "&&"
517 << cast<loc::GotoLabel>(this)->getLabel()->getID()->getName();
518 break;
519
520 case loc::MemRegionKind:
521 Out << '&' << cast<loc::MemRegionVal>(this)->getRegion()->getString();
522 break;
523
524 case loc::FuncValKind:
525 Out << "function "
526 << cast<loc::FuncVal>(this)->getDecl()->getIdentifier()->getName();
527 break;
528
Zhongxing Xu9012bff2008-10-24 06:00:12 +0000529 default:
530 assert (false && "Pretty-printing not implemented for this Loc.");
531 break;
532 }
533}