blob: 8861f576f35360dfde3974806985db3088493267 [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
125 if (!isa<ConcreteIntLValue>(*this))
126 return InvalidValue();
127
128 APSInt V = cast<ConcreteIntLValue>(this)->getValue();
129 QualType T = CastExpr->getType();
130 V.setIsUnsigned(T->isUnsignedIntegerType());
131 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
132 return ConcreteInt(ValMgr.getValue(V));
133}
134
135RValue NonLValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const {
136 if (!isa<ConcreteInt>(this))
137 return InvalidValue();
138
139 APSInt V = cast<ConcreteInt>(this)->getValue();
140 QualType T = CastExpr->getType();
141 V.setIsUnsigned(T->isUnsignedIntegerType());
142 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
143
144 if (CastExpr->getType()->isPointerType())
145 return ConcreteIntLValue(ValMgr.getValue(V));
146 else
147 return ConcreteInt(ValMgr.getValue(V));
148}
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()) {
156 case ConcreteIntKind:
157 return cast<ConcreteInt>(this)->UnaryMinus(ValMgr, U);
158 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()) {
165 case ConcreteIntKind:
166 return cast<ConcreteInt>(this)->BitwiseComplement(ValMgr);
167 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)\
174case (k1##Kind*NumNonLValueKind+k2##Kind):\
175return cast<k1>(*this).Op(ValMgr,cast<k2>(RHS));
176
177#define NONLVALUE_DISPATCH(Op)\
178switch (getSubKind()*NumNonLValueKind+RHS.getSubKind()){\
179NONLVALUE_DISPATCH_CASE(ConcreteInt,ConcreteInt,Op)\
180default:\
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
234 case ConcreteIntLValueKind: {
235 bool b = cast<ConcreteIntLValue>(this)->getValue() ==
236 cast<ConcreteIntLValue>(RHS).getValue();
237
238 return NonLValue::GetIntTruthValue(ValMgr, b);
239 }
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000240
241 case LValueDeclKind: {
242 bool b = cast<LValueDecl>(*this) == cast<LValueDecl>(RHS);
243 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 Kremeneka6e4d212008-02-01 06:36:40 +0000257 case ConcreteIntLValueKind: {
258 bool b = cast<ConcreteIntLValue>(this)->getValue() !=
259 cast<ConcreteIntLValue>(RHS).getValue();
260
261 return NonLValue::GetIntTruthValue(ValMgr, b);
262 }
263
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000264 case LValueDeclKind: {
265 bool b = cast<LValueDecl>(*this) != cast<LValueDecl>(RHS);
266 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
279 return ConcreteInt(ValMgr.getValue(X, T, Loc));
280}
281
282NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
283 return ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
284 I->getType()->isUnsignedIntegerType())));
285}
286
287RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
288 QualType T = D->getType();
289
290 if (T->isPointerType() || T->isReferenceType())
291 return SymbolicLValue(SymMgr.getSymbol(D));
292 else
293 return SymbolicNonLValue(SymMgr.getSymbol(D));
294}
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()) {
325 case ConcreteIntKind:
326 Out << cast<ConcreteInt>(this)->getValue().toString();
327 break;
328
329 case SymbolicNonLValueKind:
330 Out << '$' << cast<SymbolicNonLValue>(this)->getSymbolID();
331 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()) {
341 case ConcreteIntLValueKind:
342 Out << cast<ConcreteIntLValue>(this)->getValue().toString()
343 << " (LValue)";
344 break;
345
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000346 case SymbolicLValueKind:
347 Out << '$' << cast<SymbolicLValue>(this)->getSymbolID();
348 break;
349
350 case LValueDeclKind:
351 Out << '&'
352 << cast<LValueDecl>(this)->getDecl()->getIdentifier()->getName();
353 break;
354
355 default:
356 assert (false && "Pretty-printed not implemented for this LValue.");
357 break;
358 }
359}