blob: 0fc03dda588360acb6f37f7eef24aa5e95bcbe3a [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
Ted Kremenekcc409b72008-02-14 17:30:51 +000015#include "clang/Analysis/PathSensitive/RValues.h"
Ted Kremenekd70d0b02008-02-16 01:12:31 +000016#include "llvm/Support/Streams.h"
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000017
18using namespace clang;
19using llvm::dyn_cast;
20using llvm::cast;
21using llvm::APSInt;
22
23//===----------------------------------------------------------------------===//
Ted Kremenek90e14812008-02-14 23:25:54 +000024// Symbol Iteration.
25//===----------------------------------------------------------------------===//
Ted Kremeneka6e4d212008-02-01 06:36:40 +000026
Ted Kremenek90e14812008-02-14 23:25:54 +000027RValue::symbol_iterator RValue::symbol_begin() const {
28 if (isa<LValue>(this)) {
29 if (isa<lval::SymbolVal>(this))
30 return (symbol_iterator) (&Data);
31 }
32 else {
33 if (isa<nonlval::SymbolVal>(this))
34 return (symbol_iterator) (&Data);
35 else if (isa<nonlval::SymIntConstraintVal>(this)) {
36 const SymIntConstraint& C =
37 cast<nonlval::SymIntConstraintVal>(this)->getConstraint();
38 return (symbol_iterator) &C.getSymbol();
39 }
40 }
41
42 return NULL;
43}
44
45RValue::symbol_iterator RValue::symbol_end() const {
46 symbol_iterator X = symbol_begin();
47 return X ? X+1 : NULL;
48}
Ted Kremeneka6e4d212008-02-01 06:36:40 +000049
Ted Kremenekcf78b6a2008-02-06 22:50:25 +000050//===----------------------------------------------------------------------===//
51// Transfer function dispatch for Non-LValues.
52//===----------------------------------------------------------------------===//
Ted Kremeneka6e4d212008-02-01 06:36:40 +000053
Ted Kremenekcf78b6a2008-02-06 22:50:25 +000054nonlval::ConcreteInt
55nonlval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr,
56 BinaryOperator::Opcode Op,
57 const nonlval::ConcreteInt& RHS) const {
58
Ted Kremenekd70d0b02008-02-16 01:12:31 +000059 return ValMgr.EvaluateAPSInt(Op, getValue(), RHS.getValue());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +000060}
61
62
63 // Bitwise-Complement.
64
Ted Kremenekcf78b6a2008-02-06 22:50:25 +000065
66nonlval::ConcreteInt
67nonlval::ConcreteInt::EvalComplement(ValueManager& ValMgr) const {
68 return ValMgr.getValue(~getValue());
69}
70
Ted Kremenekcf78b6a2008-02-06 22:50:25 +000071 // Unary Minus.
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000072
Ted Kremenekcf78b6a2008-02-06 22:50:25 +000073nonlval::ConcreteInt
74nonlval::ConcreteInt::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
75 assert (U->getType() == U->getSubExpr()->getType());
76 assert (U->getType()->isIntegerType());
77 return ValMgr.getValue(-getValue());
Ted Kremenekc5d3b4c2008-02-04 16:58:30 +000078}
79
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000080//===----------------------------------------------------------------------===//
81// Transfer function dispatch for LValues.
82//===----------------------------------------------------------------------===//
83
Ted Kremenekcf78b6a2008-02-06 22:50:25 +000084lval::ConcreteInt
85lval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr,
86 BinaryOperator::Opcode Op,
87 const lval::ConcreteInt& RHS) const {
88
89 assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub ||
90 (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE));
91
Ted Kremenekd70d0b02008-02-16 01:12:31 +000092 return ValMgr.EvaluateAPSInt(Op, getValue(), RHS.getValue());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +000093}
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000094
95NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +000096 switch (getSubKind()) {
97 default:
98 assert(false && "EQ not implemented for this LValue.");
Ted Kremenek22031182008-02-08 02:57:34 +000099 return cast<NonLValue>(UnknownVal());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000100
Ted Kremenek0806acf2008-02-05 23:08:41 +0000101 case lval::ConcreteIntKind:
102 if (isa<lval::ConcreteInt>(RHS)) {
103 bool b = cast<lval::ConcreteInt>(this)->getValue() ==
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000104 cast<lval::ConcreteInt>(RHS).getValue();
105
Ted Kremenek0806acf2008-02-05 23:08:41 +0000106 return NonLValue::GetIntTruthValue(ValMgr, b);
107 }
108 else if (isa<lval::SymbolVal>(RHS)) {
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000109
Ted Kremenek0806acf2008-02-05 23:08:41 +0000110 const SymIntConstraint& C =
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000111 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
112 BinaryOperator::EQ,
113 cast<lval::ConcreteInt>(this)->getValue());
Ted Kremenek0806acf2008-02-05 23:08:41 +0000114
115 return nonlval::SymIntConstraintVal(C);
116 }
117
118 break;
119
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000120 case lval::SymbolValKind: {
121 if (isa<lval::ConcreteInt>(RHS)) {
122
123 const SymIntConstraint& C =
Ted Kremenek0806acf2008-02-05 23:08:41 +0000124 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
125 BinaryOperator::EQ,
126 cast<lval::ConcreteInt>(RHS).getValue());
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000127
128 return nonlval::SymIntConstraintVal(C);
129 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000130
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000131 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement unification.");
132
133 break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000134 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000135
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000136 case lval::DeclValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000137 if (isa<lval::DeclVal>(RHS)) {
138 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
139 return NonLValue::GetIntTruthValue(ValMgr, b);
140 }
141
142 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000143 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000144
145 return NonLValue::GetIntTruthValue(ValMgr, false);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000146}
147
148NonLValue LValue::NE(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000149 switch (getSubKind()) {
150 default:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000151 assert(false && "NE not implemented for this LValue.");
Ted Kremenek22031182008-02-08 02:57:34 +0000152 return cast<NonLValue>(UnknownVal());
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000153
Ted Kremenek0806acf2008-02-05 23:08:41 +0000154 case lval::ConcreteIntKind:
155 if (isa<lval::ConcreteInt>(RHS)) {
156 bool b = cast<lval::ConcreteInt>(this)->getValue() !=
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000157 cast<lval::ConcreteInt>(RHS).getValue();
Ted Kremenek0806acf2008-02-05 23:08:41 +0000158
159 return NonLValue::GetIntTruthValue(ValMgr, b);
160 }
161 else if (isa<lval::SymbolVal>(RHS)) {
162
163 const SymIntConstraint& C =
164 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
165 BinaryOperator::NE,
166 cast<lval::ConcreteInt>(this)->getValue());
167
168 return nonlval::SymIntConstraintVal(C);
169 }
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000170
Ted Kremenek0806acf2008-02-05 23:08:41 +0000171 break;
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000172
Ted Kremenek0806acf2008-02-05 23:08:41 +0000173 case lval::SymbolValKind: {
174 if (isa<lval::ConcreteInt>(RHS)) {
175
176 const SymIntConstraint& C =
177 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
178 BinaryOperator::NE,
179 cast<lval::ConcreteInt>(RHS).getValue());
180
181 return nonlval::SymIntConstraintVal(C);
182 }
183
184 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement sym !=.");
185
186 break;
187 }
188
189 case lval::DeclValKind:
190 if (isa<lval::DeclVal>(RHS)) {
191 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
192 return NonLValue::GetIntTruthValue(ValMgr, b);
193 }
194
195 break;
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000196 }
Ted Kremenek0806acf2008-02-05 23:08:41 +0000197
198 return NonLValue::GetIntTruthValue(ValMgr, true);
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000199}
200
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000201
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000202
203//===----------------------------------------------------------------------===//
204// Utility methods for constructing Non-LValues.
205//===----------------------------------------------------------------------===//
206
207NonLValue NonLValue::GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
208 SourceLocation Loc) {
209
Ted Kremenek329f8542008-02-05 21:52:21 +0000210 return nonlval::ConcreteInt(ValMgr.getValue(X, T, Loc));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000211}
212
213NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000214 return nonlval::ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
215 I->getType()->isUnsignedIntegerType())));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000216}
217
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000218NonLValue NonLValue::GetIntTruthValue(ValueManager& ValMgr, bool b) {
219 return nonlval::ConcreteInt(ValMgr.getTruthValue(b));
220}
221
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000222RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
223 QualType T = D->getType();
224
225 if (T->isPointerType() || T->isReferenceType())
Ted Kremenek329f8542008-02-05 21:52:21 +0000226 return lval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000227 else
Ted Kremenek329f8542008-02-05 21:52:21 +0000228 return nonlval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000229}
230
Ted Kremenek2a502572008-02-12 21:37:56 +0000231//===----------------------------------------------------------------------===//
232// Utility methods for constructing LValues.
233//===----------------------------------------------------------------------===//
234
235LValue LValue::GetValue(AddrLabelExpr* E) {
236 return lval::GotoLabel(E->getLabel());
Ted Kremenek5b6dc2d2008-02-07 01:08:27 +0000237}
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000238
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000239//===----------------------------------------------------------------------===//
240// Pretty-Printing.
241//===----------------------------------------------------------------------===//
242
Ted Kremenek2a502572008-02-12 21:37:56 +0000243void RValue::print() const {
244 print(*llvm::cerr.stream());
245}
246
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000247void RValue::print(std::ostream& Out) const {
248 switch (getBaseKind()) {
Ted Kremenek53c641a2008-02-08 03:02:48 +0000249 case UnknownKind:
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000250 Out << "Invalid";
251 break;
252
253 case NonLValueKind:
254 cast<NonLValue>(this)->print(Out);
255 break;
256
257 case LValueKind:
258 cast<LValue>(this)->print(Out);
259 break;
260
261 case UninitializedKind:
262 Out << "Uninitialized";
263 break;
264
265 default:
266 assert (false && "Invalid RValue.");
267 }
268}
269
Ted Kremenek0806acf2008-02-05 23:08:41 +0000270static void printOpcode(std::ostream& Out, BinaryOperator::Opcode Op) {
Ted Kremenek50d0ac22008-02-15 22:09:30 +0000271 switch (Op) {
272 case BinaryOperator::Mul: Out << "*"; break;
273 case BinaryOperator::Div: Out << "/"; break;
274 case BinaryOperator::Rem: Out << "%" ; break;
Ted Kremenek7e593362008-02-07 15:20:13 +0000275 case BinaryOperator::Add: Out << "+" ; break;
276 case BinaryOperator::Sub: Out << "-" ; break;
Ted Kremenek50d0ac22008-02-15 22:09:30 +0000277 case BinaryOperator::Shl: Out << "<<" ; break;
278 case BinaryOperator::Shr: Out << ">>" ; break;
279 case BinaryOperator::LT: Out << "<" ; break;
280 case BinaryOperator::GT: Out << ">" ; break;
281 case BinaryOperator::LE: Out << "<=" ; break;
282 case BinaryOperator::GE: Out << ">=" ; break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000283 case BinaryOperator::EQ: Out << "=="; break;
284 case BinaryOperator::NE: Out << "!="; break;
Ted Kremenek50d0ac22008-02-15 22:09:30 +0000285 case BinaryOperator::And: Out << "&" ; break;
286 case BinaryOperator::Xor: Out << "^" ; break;
287 case BinaryOperator::Or: Out << "|" ; break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000288 default: assert(false && "Not yet implemented.");
289 }
290}
291
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000292void NonLValue::print(std::ostream& Out) const {
293 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000294 case nonlval::ConcreteIntKind:
295 Out << cast<nonlval::ConcreteInt>(this)->getValue().toString();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000296
297 if (cast<nonlval::ConcreteInt>(this)->getValue().isUnsigned())
298 Out << 'U';
299
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000300 break;
301
Ted Kremenek329f8542008-02-05 21:52:21 +0000302 case nonlval::SymbolValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000303 Out << '$' << cast<nonlval::SymbolVal>(this)->getSymbol();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000304 break;
Ted Kremenek0806acf2008-02-05 23:08:41 +0000305
306 case nonlval::SymIntConstraintValKind: {
307 const nonlval::SymIntConstraintVal& C =
308 *cast<nonlval::SymIntConstraintVal>(this);
309
310 Out << '$' << C.getConstraint().getSymbol() << ' ';
311 printOpcode(Out, C.getConstraint().getOpcode());
312 Out << ' ' << C.getConstraint().getInt().toString();
Ted Kremenekcf78b6a2008-02-06 22:50:25 +0000313
314 if (C.getConstraint().getInt().isUnsigned())
315 Out << 'U';
316
Ted Kremenek0806acf2008-02-05 23:08:41 +0000317 break;
318 }
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000319
320 default:
321 assert (false && "Pretty-printed not implemented for this NonLValue.");
322 break;
323 }
324}
325
Ted Kremenekd131c4f2008-02-07 05:48:01 +0000326
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000327void LValue::print(std::ostream& Out) const {
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000328 switch (getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000329 case lval::ConcreteIntKind:
330 Out << cast<lval::ConcreteInt>(this)->getValue().toString()
Ted Kremeneka6e4d212008-02-01 06:36:40 +0000331 << " (LValue)";
332 break;
333
Ted Kremenek329f8542008-02-05 21:52:21 +0000334 case lval::SymbolValKind:
Ted Kremenek0806acf2008-02-05 23:08:41 +0000335 Out << '$' << cast<lval::SymbolVal>(this)->getSymbol();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000336 break;
Ted Kremenek2a502572008-02-12 21:37:56 +0000337
338 case lval::GotoLabelKind:
339 Out << "&&"
340 << cast<lval::GotoLabel>(this)->getLabel()->getID()->getName();
341 break;
Ted Kremenek08b66252008-02-06 04:31:33 +0000342
Ted Kremenek329f8542008-02-05 21:52:21 +0000343 case lval::DeclValKind:
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000344 Out << '&'
Ted Kremenekde434242008-02-19 01:44:53 +0000345 << cast<lval::DeclVal>(this)->getDecl()->getIdentifier()->getName();
346 break;
347
348 case lval::FuncValKind:
349 Out << "function "
350 << cast<lval::FuncVal>(this)->getDecl()->getIdentifier()->getName();
Ted Kremeneka90ccfe2008-01-31 19:34:24 +0000351 break;
352
353 default:
354 assert (false && "Pretty-printed not implemented for this LValue.");
355 break;
356 }
357}
Ted Kremenekd131c4f2008-02-07 05:48:01 +0000358