blob: fba59b42ac4769b80821a783675d2e73e6863a10 [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//
10// This files defines RValue, LValue, and NonLValue, classes that represent
11// abstract r-values for use with path-sensitive value tracking.
12//
13//===----------------------------------------------------------------------===//
14
15#include "RValues.h"
16
17using namespace clang;
18using llvm::dyn_cast;
19using llvm::cast;
20using llvm::APSInt;
21
22//===----------------------------------------------------------------------===//
23// SymbolManager.
24//===----------------------------------------------------------------------===//
25
26SymbolID SymbolManager::getSymbol(ParmVarDecl* D) {
27 SymbolID& X = DataToSymbol[D];
28
29 if (!X.isInitialized()) {
30 X = SymbolToData.size();
31 SymbolToData.push_back(D);
32 }
33
34 return X;
35}
36
37SymbolManager::SymbolManager() {}
38SymbolManager::~SymbolManager() {}
39
40//===----------------------------------------------------------------------===//
Ted Kremenek1fbdb022008-02-05 21:32:43 +000041// Values and ValueManager.
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000042//===----------------------------------------------------------------------===//
43
44ValueManager::~ValueManager() {
45 // Note that the dstor for the contents of APSIntSet will never be called,
46 // so we iterate over the set and invoke the dstor for each APSInt. This
47 // frees an aux. memory allocated to represent very large constants.
48 for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
49 I->getValue().~APSInt();
50}
51
Ted Kremenek1fbdb022008-02-05 21:32:43 +000052const APSInt& ValueManager::getValue(const APSInt& X) {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000053 llvm::FoldingSetNodeID ID;
54 void* InsertPos;
55 typedef llvm::FoldingSetNodeWrapper<APSInt> FoldNodeTy;
56
57 X.Profile(ID);
58 FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
59
60 if (!P) {
61 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
62 new (P) FoldNodeTy(X);
63 APSIntSet.InsertNode(P, InsertPos);
64 }
65
66 return *P;
67}
68
Ted Kremenek1fbdb022008-02-05 21:32:43 +000069const APSInt& ValueManager::getValue(uint64_t X, unsigned BitWidth,
70 bool isUnsigned) {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000071 APSInt V(BitWidth, isUnsigned);
72 V = X;
73 return getValue(V);
74}
75
Ted Kremenek1fbdb022008-02-05 21:32:43 +000076const APSInt& ValueManager::getValue(uint64_t X, QualType T,
77 SourceLocation Loc) {
78
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000079 unsigned bits = Ctx.getTypeSize(T, Loc);
80 APSInt V(bits, T->isUnsignedIntegerType());
81 V = X;
82 return getValue(V);
83}
84
Ted Kremenek1fbdb022008-02-05 21:32:43 +000085const SymIntConstraint&
86ValueManager::getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
87 const llvm::APSInt& V) {
88
89 llvm::FoldingSetNodeID ID;
90 SymIntConstraint::Profile(ID, sym, Op, V);
91 void* InsertPos;
92
93 SymIntConstraint* C = SymIntCSet.FindNodeOrInsertPos(ID, InsertPos);
94
95 if (!C) {
96 C = (SymIntConstraint*) BPAlloc.Allocate<SymIntConstraint>();
97 new (C) SymIntConstraint(sym, Op, V);
98 SymIntCSet.InsertNode(C, InsertPos);
99 }
100
101 return *C;
102}
103
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000104//===----------------------------------------------------------------------===//
105// Transfer function for Casts.
106//===----------------------------------------------------------------------===//
107
108RValue RValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const {
109 switch (getBaseKind()) {
110 default: assert(false && "Invalid RValue."); break;
111 case LValueKind: return cast<LValue>(this)->Cast(ValMgr, CastExpr);
112 case NonLValueKind: return cast<NonLValue>(this)->Cast(ValMgr, CastExpr);
113 case UninitializedKind: case InvalidKind: break;
114 }
115
116 return *this;
117}
118
119RValue LValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const {
120 if (CastExpr->getType()->isPointerType())
121 return *this;
122
123 assert (CastExpr->getType()->isIntegerType());
124
Ted Kremenek329f8542008-02-05 21:52:21 +0000125 if (!isa<lval::ConcreteInt>(*this))
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000126 return InvalidValue();
127
Ted Kremenek329f8542008-02-05 21:52:21 +0000128 APSInt V = cast<lval::ConcreteInt>(this)->getValue();
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000129 QualType T = CastExpr->getType();
130 V.setIsUnsigned(T->isUnsignedIntegerType());
131 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
Ted Kremenek329f8542008-02-05 21:52:21 +0000132 return nonlval::ConcreteInt(ValMgr.getValue(V));
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000133}
134
135RValue NonLValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const {
Ted Kremenek329f8542008-02-05 21:52:21 +0000136 if (!isa<nonlval::ConcreteInt>(this))
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000137 return InvalidValue();
138
Ted Kremenek329f8542008-02-05 21:52:21 +0000139 APSInt V = cast<nonlval::ConcreteInt>(this)->getValue();
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000140 QualType T = CastExpr->getType();
Ted Kremenek08b66252008-02-06 04:31:33 +0000141 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000142 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
143
144 if (CastExpr->getType()->isPointerType())
Ted Kremenek329f8542008-02-05 21:52:21 +0000145 return lval::ConcreteInt(ValMgr.getValue(V));
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000146 else
Ted Kremenek329f8542008-02-05 21:52:21 +0000147 return nonlval::ConcreteInt(ValMgr.getValue(V));
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000148}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000149
150//===----------------------------------------------------------------------===//
151// Transfer function dispatch for Non-LValues.
152//===----------------------------------------------------------------------===//
153
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000154NonLValue NonLValue::UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const {
155 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000156 case nonlval::ConcreteIntKind:
157 return cast<nonlval::ConcreteInt>(this)->UnaryMinus(ValMgr, U);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000158 default:
159 return cast<NonLValue>(InvalidValue());
160 }
161}
162
Ted Kremenekc5d3b4c2008-02-04 16:58:30 +0000163NonLValue NonLValue::BitwiseComplement(ValueManager& ValMgr) const {
164 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000165 case nonlval::ConcreteIntKind:
166 return cast<nonlval::ConcreteInt>(this)->BitwiseComplement(ValMgr);
Ted Kremenekc5d3b4c2008-02-04 16:58:30 +0000167 default:
168 return cast<NonLValue>(InvalidValue());
169 }
170}
171
172
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000173#define NONLVALUE_DISPATCH_CASE(k1,k2,Op)\
Ted Kremenek329f8542008-02-05 21:52:21 +0000174case (k1##Kind*nonlval::NumKind+k2##Kind):\
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000175return cast<k1>(*this).Op(ValMgr,cast<k2>(RHS));
176
177#define NONLVALUE_DISPATCH(Op)\
Ted Kremenek329f8542008-02-05 21:52:21 +0000178switch (getSubKind()*nonlval::NumKind+RHS.getSubKind()){\
179NONLVALUE_DISPATCH_CASE(nonlval::ConcreteInt,nonlval::ConcreteInt,Op)\
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000180default:\
181if (getBaseKind() == UninitializedKind ||\
182RHS.getBaseKind() == UninitializedKind)\
183return cast<NonLValue>(UninitializedValue());\
184assert (!isValid() || !RHS.isValid() && "Missing case.");\
185break;\
186}\
187return cast<NonLValue>(InvalidValue());
188
189NonLValue NonLValue::Add(ValueManager& ValMgr, const NonLValue& RHS) const {
190 NONLVALUE_DISPATCH(Add)
191}
192
193NonLValue NonLValue::Sub(ValueManager& ValMgr, const NonLValue& RHS) const {
194 NONLVALUE_DISPATCH(Sub)
195}
196
197NonLValue NonLValue::Mul(ValueManager& ValMgr, const NonLValue& RHS) const {
198 NONLVALUE_DISPATCH(Mul)
199}
200
201NonLValue NonLValue::Div(ValueManager& ValMgr, const NonLValue& RHS) const {
202 NONLVALUE_DISPATCH(Div)
203}
204
205NonLValue NonLValue::Rem(ValueManager& ValMgr, const NonLValue& RHS) const {
206 NONLVALUE_DISPATCH(Rem)
207}
208
209NonLValue NonLValue::EQ(ValueManager& ValMgr, const NonLValue& RHS) const {
210 NONLVALUE_DISPATCH(EQ)
211}
212
213NonLValue NonLValue::NE(ValueManager& ValMgr, const NonLValue& RHS) const {
214 NONLVALUE_DISPATCH(NE)
215}
216
217#undef NONLVALUE_DISPATCH_CASE
218#undef NONLVALUE_DISPATCH
219
220//===----------------------------------------------------------------------===//
221// Transfer function dispatch for LValues.
222//===----------------------------------------------------------------------===//
223
224
225NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000226 switch (getSubKind()) {
227 default:
228 assert(false && "EQ not implemented for this LValue.");
229 return cast<NonLValue>(InvalidValue());
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000230
Ted Kremenek0806acf2008-02-05 23:08:41 +0000231 case lval::ConcreteIntKind:
232 if (isa<lval::ConcreteInt>(RHS)) {
233 bool b = cast<lval::ConcreteInt>(this)->getValue() ==
234 cast<lval::ConcreteInt>(RHS).getValue();
235
236 return NonLValue::GetIntTruthValue(ValMgr, b);
237 }
238 else if (isa<lval::SymbolVal>(RHS)) {
239
240 const SymIntConstraint& C =
241 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
242 BinaryOperator::EQ,
243 cast<lval::ConcreteInt>(this)->getValue());
244
245 return nonlval::SymIntConstraintVal(C);
246 }
247
248 break;
249
250 case lval::SymbolValKind: {
251 if (isa<lval::ConcreteInt>(RHS)) {
252
253 const SymIntConstraint& C =
254 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
255 BinaryOperator::EQ,
256 cast<lval::ConcreteInt>(RHS).getValue());
257
258 return nonlval::SymIntConstraintVal(C);
259 }
260
261 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement unification.");
262
263 break;
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000264 }
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000265
Ted Kremenek0806acf2008-02-05 23:08:41 +0000266 case lval::DeclValKind:
267 if (isa<lval::DeclVal>(RHS)) {
268 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
269 return NonLValue::GetIntTruthValue(ValMgr, b);
270 }
271
272 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000273 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000274
275 return NonLValue::GetIntTruthValue(ValMgr, false);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000276}
277
278NonLValue LValue::NE(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000279 switch (getSubKind()) {
280 default:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000281 assert(false && "NE not implemented for this LValue.");
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000282 return cast<NonLValue>(InvalidValue());
283
Ted Kremenek0806acf2008-02-05 23:08:41 +0000284 case lval::ConcreteIntKind:
285 if (isa<lval::ConcreteInt>(RHS)) {
286 bool b = cast<lval::ConcreteInt>(this)->getValue() !=
287 cast<lval::ConcreteInt>(RHS).getValue();
288
289 return NonLValue::GetIntTruthValue(ValMgr, b);
290 }
291 else if (isa<lval::SymbolVal>(RHS)) {
292
293 const SymIntConstraint& C =
294 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
295 BinaryOperator::NE,
296 cast<lval::ConcreteInt>(this)->getValue());
297
298 return nonlval::SymIntConstraintVal(C);
299 }
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000300
Ted Kremenek0806acf2008-02-05 23:08:41 +0000301 break;
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000302
Ted Kremenek0806acf2008-02-05 23:08:41 +0000303 case lval::SymbolValKind: {
304 if (isa<lval::ConcreteInt>(RHS)) {
305
306 const SymIntConstraint& C =
307 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
308 BinaryOperator::NE,
309 cast<lval::ConcreteInt>(RHS).getValue());
310
311 return nonlval::SymIntConstraintVal(C);
312 }
313
314 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement sym !=.");
315
316 break;
317 }
318
319 case lval::DeclValKind:
320 if (isa<lval::DeclVal>(RHS)) {
321 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
322 return NonLValue::GetIntTruthValue(ValMgr, b);
323 }
324
325 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000326 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000327
328 return NonLValue::GetIntTruthValue(ValMgr, true);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000329}
330
331
332//===----------------------------------------------------------------------===//
333// Utility methods for constructing Non-LValues.
334//===----------------------------------------------------------------------===//
335
336NonLValue NonLValue::GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
337 SourceLocation Loc) {
338
Ted Kremenek329f8542008-02-05 21:52:21 +0000339 return nonlval::ConcreteInt(ValMgr.getValue(X, T, Loc));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000340}
341
342NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000343 return nonlval::ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
344 I->getType()->isUnsignedIntegerType())));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000345}
346
347RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
348 QualType T = D->getType();
349
350 if (T->isPointerType() || T->isReferenceType())
Ted Kremenek329f8542008-02-05 21:52:21 +0000351 return lval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000352 else
Ted Kremenek329f8542008-02-05 21:52:21 +0000353 return nonlval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000354}
355
356//===----------------------------------------------------------------------===//
357// Pretty-Printing.
358//===----------------------------------------------------------------------===//
359
360void RValue::print(std::ostream& Out) const {
361 switch (getBaseKind()) {
362 case InvalidKind:
363 Out << "Invalid";
364 break;
365
366 case NonLValueKind:
367 cast<NonLValue>(this)->print(Out);
368 break;
369
370 case LValueKind:
371 cast<LValue>(this)->print(Out);
372 break;
373
374 case UninitializedKind:
375 Out << "Uninitialized";
376 break;
377
378 default:
379 assert (false && "Invalid RValue.");
380 }
381}
382
Ted Kremenek0806acf2008-02-05 23:08:41 +0000383static void printOpcode(std::ostream& Out, BinaryOperator::Opcode Op) {
384 switch (Op) {
385 case BinaryOperator::EQ: Out << "=="; break;
386 case BinaryOperator::NE: Out << "!="; break;
387 default: assert(false && "Not yet implemented.");
388 }
389}
390
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000391void NonLValue::print(std::ostream& Out) const {
392 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000393 case nonlval::ConcreteIntKind:
394 Out << cast<nonlval::ConcreteInt>(this)->getValue().toString();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000395 break;
396
Ted Kremenek329f8542008-02-05 21:52:21 +0000397 case nonlval::SymbolValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000398 Out << '$' << cast<nonlval::SymbolVal>(this)->getSymbol();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000399 break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000400
401 case nonlval::SymIntConstraintValKind: {
402 const nonlval::SymIntConstraintVal& C =
403 *cast<nonlval::SymIntConstraintVal>(this);
404
405 Out << '$' << C.getConstraint().getSymbol() << ' ';
406 printOpcode(Out, C.getConstraint().getOpcode());
407 Out << ' ' << C.getConstraint().getInt().toString();
408 break;
409 }
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000410
411 default:
412 assert (false && "Pretty-printed not implemented for this NonLValue.");
413 break;
414 }
415}
416
Ted Kremenek0806acf2008-02-05 23:08:41 +0000417
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000418void LValue::print(std::ostream& Out) const {
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000419 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000420 case lval::ConcreteIntKind:
421 Out << cast<lval::ConcreteInt>(this)->getValue().toString()
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000422 << " (LValue)";
423 break;
424
Ted Kremenek329f8542008-02-05 21:52:21 +0000425 case lval::SymbolValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000426 Out << '$' << cast<lval::SymbolVal>(this)->getSymbol();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000427 break;
Ted Kremenek08b66252008-02-06 04:31:33 +0000428
Ted Kremenek329f8542008-02-05 21:52:21 +0000429 case lval::DeclValKind:
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000430 Out << '&'
Ted Kremenek329f8542008-02-05 21:52:21 +0000431 << cast<lval::DeclVal>(this)->getDecl()->getIdentifier()->getName();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000432 break;
433
434 default:
435 assert (false && "Pretty-printed not implemented for this LValue.");
436 break;
437 }
438}