blob: c5c5bdeaa8b4eef03886fdca9c6e1b1ccf7902bf [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();
141 V.setIsUnsigned(T->isUnsignedIntegerType());
142 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 {
226 if (getSubKind() != RHS.getSubKind())
227 return NonLValue::GetIntTruthValue(ValMgr, false);
228
229 switch (getSubKind()) {
230 default:
231 assert(false && "EQ not implemented for this LValue.");
232 return cast<NonLValue>(InvalidValue());
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000233
Ted Kremenek329f8542008-02-05 21:52:21 +0000234 case lval::ConcreteIntKind: {
235 bool b = cast<lval::ConcreteInt>(this)->getValue() ==
236 cast<lval::ConcreteInt>(RHS).getValue();
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000237
238 return NonLValue::GetIntTruthValue(ValMgr, b);
239 }
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000240
Ted Kremenek329f8542008-02-05 21:52:21 +0000241 case lval::DeclValKind: {
242 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000243 return NonLValue::GetIntTruthValue(ValMgr, b);
244 }
245 }
246}
247
248NonLValue LValue::NE(ValueManager& ValMgr, const LValue& RHS) const {
249 if (getSubKind() != RHS.getSubKind())
250 return NonLValue::GetIntTruthValue(ValMgr, true);
251
252 switch (getSubKind()) {
253 default:
254 assert(false && "EQ not implemented for this LValue.");
255 return cast<NonLValue>(InvalidValue());
256
Ted Kremenek329f8542008-02-05 21:52:21 +0000257 case lval::ConcreteIntKind: {
258 bool b = cast<lval::ConcreteInt>(this)->getValue() !=
259 cast<lval::ConcreteInt>(RHS).getValue();
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000260
261 return NonLValue::GetIntTruthValue(ValMgr, b);
262 }
263
Ted Kremenek329f8542008-02-05 21:52:21 +0000264 case lval::DeclValKind: {
265 bool b = cast<lval::DeclVal>(*this) != cast<lval::DeclVal>(RHS);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000266 return NonLValue::GetIntTruthValue(ValMgr, b);
267 }
268 }
269}
270
271
272//===----------------------------------------------------------------------===//
273// Utility methods for constructing Non-LValues.
274//===----------------------------------------------------------------------===//
275
276NonLValue NonLValue::GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
277 SourceLocation Loc) {
278
Ted Kremenek329f8542008-02-05 21:52:21 +0000279 return nonlval::ConcreteInt(ValMgr.getValue(X, T, Loc));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000280}
281
282NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000283 return nonlval::ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
284 I->getType()->isUnsignedIntegerType())));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000285}
286
287RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
288 QualType T = D->getType();
289
290 if (T->isPointerType() || T->isReferenceType())
Ted Kremenek329f8542008-02-05 21:52:21 +0000291 return lval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000292 else
Ted Kremenek329f8542008-02-05 21:52:21 +0000293 return nonlval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000294}
295
296//===----------------------------------------------------------------------===//
297// Pretty-Printing.
298//===----------------------------------------------------------------------===//
299
300void RValue::print(std::ostream& Out) const {
301 switch (getBaseKind()) {
302 case InvalidKind:
303 Out << "Invalid";
304 break;
305
306 case NonLValueKind:
307 cast<NonLValue>(this)->print(Out);
308 break;
309
310 case LValueKind:
311 cast<LValue>(this)->print(Out);
312 break;
313
314 case UninitializedKind:
315 Out << "Uninitialized";
316 break;
317
318 default:
319 assert (false && "Invalid RValue.");
320 }
321}
322
323void NonLValue::print(std::ostream& Out) const {
324 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000325 case nonlval::ConcreteIntKind:
326 Out << cast<nonlval::ConcreteInt>(this)->getValue().toString();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000327 break;
328
Ted Kremenek329f8542008-02-05 21:52:21 +0000329 case nonlval::SymbolValKind:
330 Out << '$' << cast<nonlval::SymbolVal>(this)->getSymbolID();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000331 break;
332
333 default:
334 assert (false && "Pretty-printed not implemented for this NonLValue.");
335 break;
336 }
337}
338
339void LValue::print(std::ostream& Out) const {
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000340 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000341 case lval::ConcreteIntKind:
342 Out << cast<lval::ConcreteInt>(this)->getValue().toString()
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000343 << " (LValue)";
344 break;
345
Ted Kremenek329f8542008-02-05 21:52:21 +0000346 case lval::SymbolValKind:
347 Out << '$' << cast<lval::SymbolVal>(this)->getSymbolID();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000348 break;
349
Ted Kremenek329f8542008-02-05 21:52:21 +0000350 case lval::DeclValKind:
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000351 Out << '&'
Ted Kremenek329f8542008-02-05 21:52:21 +0000352 << cast<lval::DeclVal>(this)->getDecl()->getIdentifier()->getName();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000353 break;
354
355 default:
356 assert (false && "Pretty-printed not implemented for this LValue.");
357 break;
358 }
359}