blob: df6db08db2675b39b463d37ab666b3d98b49c797 [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
Ted Kremenekfeb01f62008-02-06 17:32:17 +000037QualType SymbolData::getType() const {
38 switch (getKind()) {
39 default:
40 assert (false && "getType() not implemented for this symbol.");
41
42 case ParmKind:
43 return static_cast<ParmVarDecl*>(getPtr())->getType();
44 }
45}
46
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000047SymbolManager::SymbolManager() {}
48SymbolManager::~SymbolManager() {}
49
50//===----------------------------------------------------------------------===//
Ted Kremenek1fbdb022008-02-05 21:32:43 +000051// Values and ValueManager.
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000052//===----------------------------------------------------------------------===//
53
54ValueManager::~ValueManager() {
55 // Note that the dstor for the contents of APSIntSet will never be called,
56 // so we iterate over the set and invoke the dstor for each APSInt. This
57 // frees an aux. memory allocated to represent very large constants.
58 for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
59 I->getValue().~APSInt();
60}
61
Ted Kremenek1fbdb022008-02-05 21:32:43 +000062const APSInt& ValueManager::getValue(const APSInt& X) {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000063 llvm::FoldingSetNodeID ID;
64 void* InsertPos;
65 typedef llvm::FoldingSetNodeWrapper<APSInt> FoldNodeTy;
66
67 X.Profile(ID);
68 FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
69
70 if (!P) {
71 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
72 new (P) FoldNodeTy(X);
73 APSIntSet.InsertNode(P, InsertPos);
74 }
75
76 return *P;
77}
78
Ted Kremenek1fbdb022008-02-05 21:32:43 +000079const APSInt& ValueManager::getValue(uint64_t X, unsigned BitWidth,
80 bool isUnsigned) {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000081 APSInt V(BitWidth, isUnsigned);
82 V = X;
83 return getValue(V);
84}
85
Ted Kremenek1fbdb022008-02-05 21:32:43 +000086const APSInt& ValueManager::getValue(uint64_t X, QualType T,
87 SourceLocation Loc) {
88
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000089 unsigned bits = Ctx.getTypeSize(T, Loc);
90 APSInt V(bits, T->isUnsignedIntegerType());
91 V = X;
92 return getValue(V);
93}
94
Ted Kremenek1fbdb022008-02-05 21:32:43 +000095const SymIntConstraint&
96ValueManager::getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
97 const llvm::APSInt& V) {
98
99 llvm::FoldingSetNodeID ID;
100 SymIntConstraint::Profile(ID, sym, Op, V);
101 void* InsertPos;
102
103 SymIntConstraint* C = SymIntCSet.FindNodeOrInsertPos(ID, InsertPos);
104
105 if (!C) {
106 C = (SymIntConstraint*) BPAlloc.Allocate<SymIntConstraint>();
107 new (C) SymIntConstraint(sym, Op, V);
108 SymIntCSet.InsertNode(C, InsertPos);
109 }
110
111 return *C;
112}
113
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000114//===----------------------------------------------------------------------===//
115// Transfer function for Casts.
116//===----------------------------------------------------------------------===//
117
118RValue RValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const {
119 switch (getBaseKind()) {
120 default: assert(false && "Invalid RValue."); break;
121 case LValueKind: return cast<LValue>(this)->Cast(ValMgr, CastExpr);
122 case NonLValueKind: return cast<NonLValue>(this)->Cast(ValMgr, CastExpr);
123 case UninitializedKind: case InvalidKind: break;
124 }
125
126 return *this;
127}
128
129RValue LValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const {
130 if (CastExpr->getType()->isPointerType())
131 return *this;
132
133 assert (CastExpr->getType()->isIntegerType());
134
Ted Kremenek329f8542008-02-05 21:52:21 +0000135 if (!isa<lval::ConcreteInt>(*this))
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000136 return InvalidValue();
137
Ted Kremenek329f8542008-02-05 21:52:21 +0000138 APSInt V = cast<lval::ConcreteInt>(this)->getValue();
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000139 QualType T = CastExpr->getType();
140 V.setIsUnsigned(T->isUnsignedIntegerType());
141 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
Ted Kremenek329f8542008-02-05 21:52:21 +0000142 return nonlval::ConcreteInt(ValMgr.getValue(V));
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000143}
144
145RValue NonLValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const {
Ted Kremenek329f8542008-02-05 21:52:21 +0000146 if (!isa<nonlval::ConcreteInt>(this))
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000147 return InvalidValue();
148
Ted Kremenek329f8542008-02-05 21:52:21 +0000149 APSInt V = cast<nonlval::ConcreteInt>(this)->getValue();
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000150 QualType T = CastExpr->getType();
Ted Kremenek08b66252008-02-06 04:31:33 +0000151 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000152 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
153
154 if (CastExpr->getType()->isPointerType())
Ted Kremenek329f8542008-02-05 21:52:21 +0000155 return lval::ConcreteInt(ValMgr.getValue(V));
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000156 else
Ted Kremenek329f8542008-02-05 21:52:21 +0000157 return nonlval::ConcreteInt(ValMgr.getValue(V));
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000158}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000159
160//===----------------------------------------------------------------------===//
161// Transfer function dispatch for Non-LValues.
162//===----------------------------------------------------------------------===//
163
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000164NonLValue NonLValue::UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const {
165 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000166 case nonlval::ConcreteIntKind:
167 return cast<nonlval::ConcreteInt>(this)->UnaryMinus(ValMgr, U);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000168 default:
169 return cast<NonLValue>(InvalidValue());
170 }
171}
172
Ted Kremenekc5d3b4c2008-02-04 16:58:30 +0000173NonLValue NonLValue::BitwiseComplement(ValueManager& ValMgr) const {
174 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000175 case nonlval::ConcreteIntKind:
176 return cast<nonlval::ConcreteInt>(this)->BitwiseComplement(ValMgr);
Ted Kremenekc5d3b4c2008-02-04 16:58:30 +0000177 default:
178 return cast<NonLValue>(InvalidValue());
179 }
180}
181
182
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000183#define NONLVALUE_DISPATCH_CASE(k1,k2,Op)\
Ted Kremenek329f8542008-02-05 21:52:21 +0000184case (k1##Kind*nonlval::NumKind+k2##Kind):\
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000185return cast<k1>(*this).Op(ValMgr,cast<k2>(RHS));
186
187#define NONLVALUE_DISPATCH(Op)\
Ted Kremenek329f8542008-02-05 21:52:21 +0000188switch (getSubKind()*nonlval::NumKind+RHS.getSubKind()){\
189NONLVALUE_DISPATCH_CASE(nonlval::ConcreteInt,nonlval::ConcreteInt,Op)\
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000190default:\
191if (getBaseKind() == UninitializedKind ||\
192RHS.getBaseKind() == UninitializedKind)\
193return cast<NonLValue>(UninitializedValue());\
194assert (!isValid() || !RHS.isValid() && "Missing case.");\
195break;\
196}\
197return cast<NonLValue>(InvalidValue());
198
199NonLValue NonLValue::Add(ValueManager& ValMgr, const NonLValue& RHS) const {
200 NONLVALUE_DISPATCH(Add)
201}
202
203NonLValue NonLValue::Sub(ValueManager& ValMgr, const NonLValue& RHS) const {
204 NONLVALUE_DISPATCH(Sub)
205}
206
207NonLValue NonLValue::Mul(ValueManager& ValMgr, const NonLValue& RHS) const {
208 NONLVALUE_DISPATCH(Mul)
209}
210
211NonLValue NonLValue::Div(ValueManager& ValMgr, const NonLValue& RHS) const {
212 NONLVALUE_DISPATCH(Div)
213}
214
215NonLValue NonLValue::Rem(ValueManager& ValMgr, const NonLValue& RHS) const {
216 NONLVALUE_DISPATCH(Rem)
217}
218
219NonLValue NonLValue::EQ(ValueManager& ValMgr, const NonLValue& RHS) const {
220 NONLVALUE_DISPATCH(EQ)
221}
222
223NonLValue NonLValue::NE(ValueManager& ValMgr, const NonLValue& RHS) const {
224 NONLVALUE_DISPATCH(NE)
225}
226
227#undef NONLVALUE_DISPATCH_CASE
228#undef NONLVALUE_DISPATCH
229
230//===----------------------------------------------------------------------===//
231// Transfer function dispatch for LValues.
232//===----------------------------------------------------------------------===//
233
234
235NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000236 switch (getSubKind()) {
237 default:
238 assert(false && "EQ not implemented for this LValue.");
239 return cast<NonLValue>(InvalidValue());
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000240
Ted Kremenek0806acf2008-02-05 23:08:41 +0000241 case lval::ConcreteIntKind:
242 if (isa<lval::ConcreteInt>(RHS)) {
243 bool b = cast<lval::ConcreteInt>(this)->getValue() ==
244 cast<lval::ConcreteInt>(RHS).getValue();
245
246 return NonLValue::GetIntTruthValue(ValMgr, b);
247 }
248 else if (isa<lval::SymbolVal>(RHS)) {
249
250 const SymIntConstraint& C =
251 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
252 BinaryOperator::EQ,
253 cast<lval::ConcreteInt>(this)->getValue());
254
255 return nonlval::SymIntConstraintVal(C);
256 }
257
258 break;
259
260 case lval::SymbolValKind: {
261 if (isa<lval::ConcreteInt>(RHS)) {
262
263 const SymIntConstraint& C =
264 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
265 BinaryOperator::EQ,
266 cast<lval::ConcreteInt>(RHS).getValue());
267
268 return nonlval::SymIntConstraintVal(C);
269 }
270
271 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement unification.");
272
273 break;
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000274 }
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000275
Ted Kremenek0806acf2008-02-05 23:08:41 +0000276 case lval::DeclValKind:
277 if (isa<lval::DeclVal>(RHS)) {
278 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
279 return NonLValue::GetIntTruthValue(ValMgr, b);
280 }
281
282 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000283 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000284
285 return NonLValue::GetIntTruthValue(ValMgr, false);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000286}
287
288NonLValue LValue::NE(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000289 switch (getSubKind()) {
290 default:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000291 assert(false && "NE not implemented for this LValue.");
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000292 return cast<NonLValue>(InvalidValue());
293
Ted Kremenek0806acf2008-02-05 23:08:41 +0000294 case lval::ConcreteIntKind:
295 if (isa<lval::ConcreteInt>(RHS)) {
296 bool b = cast<lval::ConcreteInt>(this)->getValue() !=
297 cast<lval::ConcreteInt>(RHS).getValue();
298
299 return NonLValue::GetIntTruthValue(ValMgr, b);
300 }
301 else if (isa<lval::SymbolVal>(RHS)) {
302
303 const SymIntConstraint& C =
304 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
305 BinaryOperator::NE,
306 cast<lval::ConcreteInt>(this)->getValue());
307
308 return nonlval::SymIntConstraintVal(C);
309 }
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000310
Ted Kremenek0806acf2008-02-05 23:08:41 +0000311 break;
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000312
Ted Kremenek0806acf2008-02-05 23:08:41 +0000313 case lval::SymbolValKind: {
314 if (isa<lval::ConcreteInt>(RHS)) {
315
316 const SymIntConstraint& C =
317 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
318 BinaryOperator::NE,
319 cast<lval::ConcreteInt>(RHS).getValue());
320
321 return nonlval::SymIntConstraintVal(C);
322 }
323
324 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement sym !=.");
325
326 break;
327 }
328
329 case lval::DeclValKind:
330 if (isa<lval::DeclVal>(RHS)) {
331 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
332 return NonLValue::GetIntTruthValue(ValMgr, b);
333 }
334
335 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000336 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000337
338 return NonLValue::GetIntTruthValue(ValMgr, true);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000339}
340
341
342//===----------------------------------------------------------------------===//
343// Utility methods for constructing Non-LValues.
344//===----------------------------------------------------------------------===//
345
346NonLValue NonLValue::GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
347 SourceLocation Loc) {
348
Ted Kremenek329f8542008-02-05 21:52:21 +0000349 return nonlval::ConcreteInt(ValMgr.getValue(X, T, Loc));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000350}
351
352NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000353 return nonlval::ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
354 I->getType()->isUnsignedIntegerType())));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000355}
356
357RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
358 QualType T = D->getType();
359
360 if (T->isPointerType() || T->isReferenceType())
Ted Kremenek329f8542008-02-05 21:52:21 +0000361 return lval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000362 else
Ted Kremenek329f8542008-02-05 21:52:21 +0000363 return nonlval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000364}
365
366//===----------------------------------------------------------------------===//
367// Pretty-Printing.
368//===----------------------------------------------------------------------===//
369
370void RValue::print(std::ostream& Out) const {
371 switch (getBaseKind()) {
372 case InvalidKind:
373 Out << "Invalid";
374 break;
375
376 case NonLValueKind:
377 cast<NonLValue>(this)->print(Out);
378 break;
379
380 case LValueKind:
381 cast<LValue>(this)->print(Out);
382 break;
383
384 case UninitializedKind:
385 Out << "Uninitialized";
386 break;
387
388 default:
389 assert (false && "Invalid RValue.");
390 }
391}
392
Ted Kremenek0806acf2008-02-05 23:08:41 +0000393static void printOpcode(std::ostream& Out, BinaryOperator::Opcode Op) {
394 switch (Op) {
395 case BinaryOperator::EQ: Out << "=="; break;
396 case BinaryOperator::NE: Out << "!="; break;
397 default: assert(false && "Not yet implemented.");
398 }
399}
400
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000401void NonLValue::print(std::ostream& Out) const {
402 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000403 case nonlval::ConcreteIntKind:
404 Out << cast<nonlval::ConcreteInt>(this)->getValue().toString();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000405 break;
406
Ted Kremenek329f8542008-02-05 21:52:21 +0000407 case nonlval::SymbolValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000408 Out << '$' << cast<nonlval::SymbolVal>(this)->getSymbol();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000409 break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000410
411 case nonlval::SymIntConstraintValKind: {
412 const nonlval::SymIntConstraintVal& C =
413 *cast<nonlval::SymIntConstraintVal>(this);
414
415 Out << '$' << C.getConstraint().getSymbol() << ' ';
416 printOpcode(Out, C.getConstraint().getOpcode());
417 Out << ' ' << C.getConstraint().getInt().toString();
418 break;
419 }
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000420
421 default:
422 assert (false && "Pretty-printed not implemented for this NonLValue.");
423 break;
424 }
425}
426
Ted Kremenek0806acf2008-02-05 23:08:41 +0000427
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000428void LValue::print(std::ostream& Out) const {
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000429 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000430 case lval::ConcreteIntKind:
431 Out << cast<lval::ConcreteInt>(this)->getValue().toString()
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000432 << " (LValue)";
433 break;
434
Ted Kremenek329f8542008-02-05 21:52:21 +0000435 case lval::SymbolValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000436 Out << '$' << cast<lval::SymbolVal>(this)->getSymbol();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000437 break;
Ted Kremenek08b66252008-02-06 04:31:33 +0000438
Ted Kremenek329f8542008-02-05 21:52:21 +0000439 case lval::DeclValKind:
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000440 Out << '&'
Ted Kremenek329f8542008-02-05 21:52:21 +0000441 << cast<lval::DeclVal>(this)->getDecl()->getIdentifier()->getName();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000442 break;
443
444 default:
445 assert (false && "Pretty-printed not implemented for this LValue.");
446 break;
447 }
448}