blob: c4041b866db4fb44466243f6d826cfef0400d959 [file] [log] [blame]
Ted Kremenek72197902008-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 Kremenek5a535ba2008-02-14 17:30:51 +000015#include "clang/Analysis/PathSensitive/RValues.h"
Ted Kremenek94e915e2008-02-16 01:12:31 +000016#include "llvm/Support/Streams.h"
Ted Kremenek72197902008-01-31 19:34:24 +000017
18using namespace clang;
19using llvm::dyn_cast;
20using llvm::cast;
21using llvm::APSInt;
22
23//===----------------------------------------------------------------------===//
Ted Kremenek0e39dcf2008-02-14 23:25:54 +000024// Symbol Iteration.
25//===----------------------------------------------------------------------===//
Ted Kremenek6e24a802008-02-01 06:36:40 +000026
Ted Kremenek0e39dcf2008-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 Kremenek6e24a802008-02-01 06:36:40 +000049
Ted Kremenek15cb0782008-02-06 22:50:25 +000050//===----------------------------------------------------------------------===//
51// Transfer function dispatch for Non-LValues.
52//===----------------------------------------------------------------------===//
Ted Kremenek6e24a802008-02-01 06:36:40 +000053
Ted Kremenek15cb0782008-02-06 22:50:25 +000054nonlval::ConcreteInt
55nonlval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr,
56 BinaryOperator::Opcode Op,
57 const nonlval::ConcreteInt& RHS) const {
58
Ted Kremenek94e915e2008-02-16 01:12:31 +000059 return ValMgr.EvaluateAPSInt(Op, getValue(), RHS.getValue());
Ted Kremenek15cb0782008-02-06 22:50:25 +000060}
61
62
63 // Bitwise-Complement.
64
Ted Kremenek15cb0782008-02-06 22:50:25 +000065
66nonlval::ConcreteInt
67nonlval::ConcreteInt::EvalComplement(ValueManager& ValMgr) const {
68 return ValMgr.getValue(~getValue());
69}
70
Ted Kremenek15cb0782008-02-06 22:50:25 +000071 // Unary Minus.
Ted Kremenek72197902008-01-31 19:34:24 +000072
Ted Kremenek15cb0782008-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 Kremenek2cb46642008-02-04 16:58:30 +000078}
79
Ted Kremenek0cd96352008-02-20 04:12:31 +000080nonlval::ConcreteInt
81nonlval::ConcreteInt::EvalPlus(ValueManager& ValMgr, UnaryOperator* U) const {
82 assert (U->getType() == U->getSubExpr()->getType());
83 assert (U->getType()->isIntegerType());
84 return ValMgr.getValue(getValue());
85}
86
Ted Kremenek72197902008-01-31 19:34:24 +000087//===----------------------------------------------------------------------===//
88// Transfer function dispatch for LValues.
89//===----------------------------------------------------------------------===//
90
Ted Kremenek15cb0782008-02-06 22:50:25 +000091lval::ConcreteInt
92lval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr,
93 BinaryOperator::Opcode Op,
94 const lval::ConcreteInt& RHS) const {
95
96 assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub ||
97 (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE));
98
Ted Kremenek94e915e2008-02-16 01:12:31 +000099 return ValMgr.EvaluateAPSInt(Op, getValue(), RHS.getValue());
Ted Kremenek15cb0782008-02-06 22:50:25 +0000100}
Ted Kremenek72197902008-01-31 19:34:24 +0000101
102NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremenek72197902008-01-31 19:34:24 +0000103 switch (getSubKind()) {
104 default:
105 assert(false && "EQ not implemented for this LValue.");
Ted Kremenekadec14b2008-02-08 02:57:34 +0000106 return cast<NonLValue>(UnknownVal());
Ted Kremenek15cb0782008-02-06 22:50:25 +0000107
Ted Kremenek81eacb22008-02-05 23:08:41 +0000108 case lval::ConcreteIntKind:
109 if (isa<lval::ConcreteInt>(RHS)) {
110 bool b = cast<lval::ConcreteInt>(this)->getValue() ==
Ted Kremenek15cb0782008-02-06 22:50:25 +0000111 cast<lval::ConcreteInt>(RHS).getValue();
112
Ted Kremenek81eacb22008-02-05 23:08:41 +0000113 return NonLValue::GetIntTruthValue(ValMgr, b);
114 }
115 else if (isa<lval::SymbolVal>(RHS)) {
Ted Kremenek15cb0782008-02-06 22:50:25 +0000116
Ted Kremenek81eacb22008-02-05 23:08:41 +0000117 const SymIntConstraint& C =
Ted Kremenek15cb0782008-02-06 22:50:25 +0000118 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
119 BinaryOperator::EQ,
120 cast<lval::ConcreteInt>(this)->getValue());
Ted Kremenek81eacb22008-02-05 23:08:41 +0000121
122 return nonlval::SymIntConstraintVal(C);
123 }
124
125 break;
126
Ted Kremenek15cb0782008-02-06 22:50:25 +0000127 case lval::SymbolValKind: {
128 if (isa<lval::ConcreteInt>(RHS)) {
129
130 const SymIntConstraint& C =
Ted Kremenek81eacb22008-02-05 23:08:41 +0000131 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
132 BinaryOperator::EQ,
133 cast<lval::ConcreteInt>(RHS).getValue());
Ted Kremenek15cb0782008-02-06 22:50:25 +0000134
135 return nonlval::SymIntConstraintVal(C);
136 }
Ted Kremenek81eacb22008-02-05 23:08:41 +0000137
Ted Kremenek15cb0782008-02-06 22:50:25 +0000138 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement unification.");
139
140 break;
Ted Kremenek81eacb22008-02-05 23:08:41 +0000141 }
Ted Kremenek81eacb22008-02-05 23:08:41 +0000142
Ted Kremenek15cb0782008-02-06 22:50:25 +0000143 case lval::DeclValKind:
Ted Kremenek81eacb22008-02-05 23:08:41 +0000144 if (isa<lval::DeclVal>(RHS)) {
145 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
146 return NonLValue::GetIntTruthValue(ValMgr, b);
147 }
148
149 break;
Ted Kremenek72197902008-01-31 19:34:24 +0000150 }
Ted Kremenek81eacb22008-02-05 23:08:41 +0000151
152 return NonLValue::GetIntTruthValue(ValMgr, false);
Ted Kremenek72197902008-01-31 19:34:24 +0000153}
154
155NonLValue LValue::NE(ValueManager& ValMgr, const LValue& RHS) const {
Ted Kremenek72197902008-01-31 19:34:24 +0000156 switch (getSubKind()) {
157 default:
Ted Kremenek81eacb22008-02-05 23:08:41 +0000158 assert(false && "NE not implemented for this LValue.");
Ted Kremenekadec14b2008-02-08 02:57:34 +0000159 return cast<NonLValue>(UnknownVal());
Ted Kremenek72197902008-01-31 19:34:24 +0000160
Ted Kremenek81eacb22008-02-05 23:08:41 +0000161 case lval::ConcreteIntKind:
162 if (isa<lval::ConcreteInt>(RHS)) {
163 bool b = cast<lval::ConcreteInt>(this)->getValue() !=
Ted Kremenek15cb0782008-02-06 22:50:25 +0000164 cast<lval::ConcreteInt>(RHS).getValue();
Ted Kremenek81eacb22008-02-05 23:08:41 +0000165
166 return NonLValue::GetIntTruthValue(ValMgr, b);
167 }
168 else if (isa<lval::SymbolVal>(RHS)) {
169
170 const SymIntConstraint& C =
171 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
172 BinaryOperator::NE,
173 cast<lval::ConcreteInt>(this)->getValue());
174
175 return nonlval::SymIntConstraintVal(C);
176 }
Ted Kremenek6e24a802008-02-01 06:36:40 +0000177
Ted Kremenek81eacb22008-02-05 23:08:41 +0000178 break;
Ted Kremenek6e24a802008-02-01 06:36:40 +0000179
Ted Kremenek81eacb22008-02-05 23:08:41 +0000180 case lval::SymbolValKind: {
181 if (isa<lval::ConcreteInt>(RHS)) {
182
183 const SymIntConstraint& C =
184 ValMgr.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
185 BinaryOperator::NE,
186 cast<lval::ConcreteInt>(RHS).getValue());
187
188 return nonlval::SymIntConstraintVal(C);
189 }
190
191 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement sym !=.");
192
193 break;
194 }
195
196 case lval::DeclValKind:
197 if (isa<lval::DeclVal>(RHS)) {
198 bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(RHS);
199 return NonLValue::GetIntTruthValue(ValMgr, b);
200 }
201
202 break;
Ted Kremenek72197902008-01-31 19:34:24 +0000203 }
Ted Kremenek81eacb22008-02-05 23:08:41 +0000204
205 return NonLValue::GetIntTruthValue(ValMgr, true);
Ted Kremenek72197902008-01-31 19:34:24 +0000206}
207
Ted Kremenek15cb0782008-02-06 22:50:25 +0000208
Ted Kremenek72197902008-01-31 19:34:24 +0000209
210//===----------------------------------------------------------------------===//
211// Utility methods for constructing Non-LValues.
212//===----------------------------------------------------------------------===//
213
214NonLValue NonLValue::GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
215 SourceLocation Loc) {
216
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000217 return nonlval::ConcreteInt(ValMgr.getValue(X, T, Loc));
Ted Kremenek72197902008-01-31 19:34:24 +0000218}
219
220NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000221 return nonlval::ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
222 I->getType()->isUnsignedIntegerType())));
Ted Kremenek72197902008-01-31 19:34:24 +0000223}
224
Ted Kremenek15cb0782008-02-06 22:50:25 +0000225NonLValue NonLValue::GetIntTruthValue(ValueManager& ValMgr, bool b) {
226 return nonlval::ConcreteInt(ValMgr.getTruthValue(b));
227}
228
Ted Kremenek72197902008-01-31 19:34:24 +0000229RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
230 QualType T = D->getType();
231
232 if (T->isPointerType() || T->isReferenceType())
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000233 return lval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremenek72197902008-01-31 19:34:24 +0000234 else
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000235 return nonlval::SymbolVal(SymMgr.getSymbol(D));
Ted Kremenek72197902008-01-31 19:34:24 +0000236}
237
Ted Kremenekad884682008-02-12 21:37:56 +0000238//===----------------------------------------------------------------------===//
239// Utility methods for constructing LValues.
240//===----------------------------------------------------------------------===//
241
242LValue LValue::GetValue(AddrLabelExpr* E) {
243 return lval::GotoLabel(E->getLabel());
Ted Kremeneke1f38b62008-02-07 01:08:27 +0000244}
Ted Kremenek15cb0782008-02-06 22:50:25 +0000245
Ted Kremenek72197902008-01-31 19:34:24 +0000246//===----------------------------------------------------------------------===//
247// Pretty-Printing.
248//===----------------------------------------------------------------------===//
249
Ted Kremenekb996ebc2008-02-20 04:02:35 +0000250void RValue::printStdErr() const {
Ted Kremenekad884682008-02-12 21:37:56 +0000251 print(*llvm::cerr.stream());
252}
253
Ted Kremenek72197902008-01-31 19:34:24 +0000254void RValue::print(std::ostream& Out) const {
255 switch (getBaseKind()) {
Ted Kremenek0428e022008-02-08 03:02:48 +0000256 case UnknownKind:
Ted Kremenek72197902008-01-31 19:34:24 +0000257 Out << "Invalid";
258 break;
259
260 case NonLValueKind:
261 cast<NonLValue>(this)->print(Out);
262 break;
263
264 case LValueKind:
265 cast<LValue>(this)->print(Out);
266 break;
267
268 case UninitializedKind:
269 Out << "Uninitialized";
270 break;
271
272 default:
273 assert (false && "Invalid RValue.");
274 }
275}
276
Ted Kremenek81eacb22008-02-05 23:08:41 +0000277static void printOpcode(std::ostream& Out, BinaryOperator::Opcode Op) {
Ted Kremenek22640ce2008-02-15 22:09:30 +0000278 switch (Op) {
279 case BinaryOperator::Mul: Out << "*"; break;
280 case BinaryOperator::Div: Out << "/"; break;
281 case BinaryOperator::Rem: Out << "%" ; break;
Ted Kremenek02b5b402008-02-07 15:20:13 +0000282 case BinaryOperator::Add: Out << "+" ; break;
283 case BinaryOperator::Sub: Out << "-" ; break;
Ted Kremenek22640ce2008-02-15 22:09:30 +0000284 case BinaryOperator::Shl: Out << "<<" ; break;
285 case BinaryOperator::Shr: Out << ">>" ; break;
286 case BinaryOperator::LT: Out << "<" ; break;
287 case BinaryOperator::GT: Out << ">" ; break;
288 case BinaryOperator::LE: Out << "<=" ; break;
289 case BinaryOperator::GE: Out << ">=" ; break;
Ted Kremenek81eacb22008-02-05 23:08:41 +0000290 case BinaryOperator::EQ: Out << "=="; break;
291 case BinaryOperator::NE: Out << "!="; break;
Ted Kremenek22640ce2008-02-15 22:09:30 +0000292 case BinaryOperator::And: Out << "&" ; break;
293 case BinaryOperator::Xor: Out << "^" ; break;
294 case BinaryOperator::Or: Out << "|" ; break;
Ted Kremenek81eacb22008-02-05 23:08:41 +0000295 default: assert(false && "Not yet implemented.");
296 }
297}
298
Ted Kremenek72197902008-01-31 19:34:24 +0000299void NonLValue::print(std::ostream& Out) const {
300 switch (getSubKind()) {
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000301 case nonlval::ConcreteIntKind:
302 Out << cast<nonlval::ConcreteInt>(this)->getValue().toString();
Ted Kremenek15cb0782008-02-06 22:50:25 +0000303
304 if (cast<nonlval::ConcreteInt>(this)->getValue().isUnsigned())
305 Out << 'U';
306
Ted Kremenek72197902008-01-31 19:34:24 +0000307 break;
308
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000309 case nonlval::SymbolValKind:
Ted Kremenek81eacb22008-02-05 23:08:41 +0000310 Out << '$' << cast<nonlval::SymbolVal>(this)->getSymbol();
Ted Kremenek72197902008-01-31 19:34:24 +0000311 break;
Ted Kremenek81eacb22008-02-05 23:08:41 +0000312
313 case nonlval::SymIntConstraintValKind: {
314 const nonlval::SymIntConstraintVal& C =
315 *cast<nonlval::SymIntConstraintVal>(this);
316
317 Out << '$' << C.getConstraint().getSymbol() << ' ';
318 printOpcode(Out, C.getConstraint().getOpcode());
319 Out << ' ' << C.getConstraint().getInt().toString();
Ted Kremenek15cb0782008-02-06 22:50:25 +0000320
321 if (C.getConstraint().getInt().isUnsigned())
322 Out << 'U';
323
Ted Kremenek81eacb22008-02-05 23:08:41 +0000324 break;
325 }
Ted Kremenek72197902008-01-31 19:34:24 +0000326
327 default:
328 assert (false && "Pretty-printed not implemented for this NonLValue.");
329 break;
330 }
331}
332
Ted Kremenek80d52d02008-02-07 05:48:01 +0000333
Ted Kremenek72197902008-01-31 19:34:24 +0000334void LValue::print(std::ostream& Out) const {
Ted Kremenek6e24a802008-02-01 06:36:40 +0000335 switch (getSubKind()) {
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000336 case lval::ConcreteIntKind:
337 Out << cast<lval::ConcreteInt>(this)->getValue().toString()
Ted Kremenek6e24a802008-02-01 06:36:40 +0000338 << " (LValue)";
339 break;
340
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000341 case lval::SymbolValKind:
Ted Kremenek81eacb22008-02-05 23:08:41 +0000342 Out << '$' << cast<lval::SymbolVal>(this)->getSymbol();
Ted Kremenek72197902008-01-31 19:34:24 +0000343 break;
Ted Kremenekad884682008-02-12 21:37:56 +0000344
345 case lval::GotoLabelKind:
346 Out << "&&"
347 << cast<lval::GotoLabel>(this)->getLabel()->getID()->getName();
348 break;
Ted Kremenek0033fbb2008-02-06 04:31:33 +0000349
Ted Kremenek1b63a3b2008-02-05 21:52:21 +0000350 case lval::DeclValKind:
Ted Kremenek72197902008-01-31 19:34:24 +0000351 Out << '&'
Ted Kremenekd9268e32008-02-19 01:44:53 +0000352 << cast<lval::DeclVal>(this)->getDecl()->getIdentifier()->getName();
353 break;
354
355 case lval::FuncValKind:
356 Out << "function "
357 << cast<lval::FuncVal>(this)->getDecl()->getIdentifier()->getName();
Ted Kremenek72197902008-01-31 19:34:24 +0000358 break;
359
360 default:
361 assert (false && "Pretty-printed not implemented for this LValue.");
362 break;
363 }
364}
Ted Kremenek80d52d02008-02-07 05:48:01 +0000365