blob: c350ab9752addab80caf130745f3c25cbf0cf876 [file] [log] [blame]
Ted Kremenekd59cccc2008-02-14 18:28:23 +00001// GRSimpleVals.cpp - Transfer functions for tracking simple values -*- 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//
Gabor Greif843e9342008-03-06 10:40:09 +000010// This file defines GRSimpleVals, a sub-class of GRTransferFuncs that
Ted Kremenekd59cccc2008-02-14 18:28:23 +000011// provides transfer functions for performing simple value tracking with
12// limited support for symbolics.
13//
14//===----------------------------------------------------------------------===//
15
16#include "GRSimpleVals.h"
Ted Kremenek52755612008-03-27 17:17:22 +000017#include "BasicObjCFoundationChecks.h"
Ted Kremenek87abc032008-04-02 22:03:53 +000018#include "clang/Basic/SourceManager.h"
Ted Kremenek4dc41cc2008-03-31 18:26:32 +000019#include "clang/Analysis/PathDiagnostic.h"
Ted Kremenek61f3e052008-04-03 04:42:52 +000020#include "clang/Analysis/PathSensitive/ValueState.h"
21#include "clang/Analysis/PathSensitive/BugReporter.h"
Ted Kremenekd71ed262008-04-10 22:16:52 +000022#include "clang/Analysis/LocalCheckers.h"
Ted Kremenek61f3e052008-04-03 04:42:52 +000023#include "llvm/Support/Compiler.h"
Ted Kremenek5c061212008-02-27 17:56:16 +000024#include <sstream>
Ted Kremenekd59cccc2008-02-14 18:28:23 +000025
26using namespace clang;
27
Ted Kremenekdd598112008-04-02 07:05:46 +000028//===----------------------------------------------------------------------===//
Ted Kremenekdd598112008-04-02 07:05:46 +000029// Utility functions.
30//===----------------------------------------------------------------------===//
Ted Kremenek50a6d0c2008-04-09 21:41:14 +000031
Chris Lattner3ae30f82008-04-06 04:22:39 +000032template <typename ITERATOR> inline
Ted Kremenek61f3e052008-04-03 04:42:52 +000033ExplodedNode<ValueState>* GetNode(ITERATOR I) {
Ted Kremenek503d6132008-04-02 05:15:22 +000034 return *I;
35}
36
Chris Lattner3ae30f82008-04-06 04:22:39 +000037template <> inline
Ted Kremenek61f3e052008-04-03 04:42:52 +000038ExplodedNode<ValueState>* GetNode(GRExprEngine::undef_arg_iterator I) {
Ted Kremenek503d6132008-04-02 05:15:22 +000039 return I->first;
40}
Ted Kremenekdd598112008-04-02 07:05:46 +000041
Ted Kremenek50a6d0c2008-04-09 21:41:14 +000042template <typename ITER>
43void GenericEmitWarnings(BugReporter& BR, const BugType& D,
44 ITER I, ITER E) {
45
46 for (; I != E; ++I) {
47 BugReport R(D);
48 BR.EmitPathWarning(R, GetNode(I));
49 }
50}
51
52//===----------------------------------------------------------------------===//
53// Bug Descriptions.
54//===----------------------------------------------------------------------===//
55
56namespace {
57
58class VISIBILITY_HIDDEN NullDeref : public BugType {
59public:
60 virtual const char* getName() const {
61 return "null dereference";
62 }
63
64 virtual const char* getDescription() const {
65 return "Dereference of null pointer.";
66 }
67
68 virtual void EmitWarnings(BugReporter& BR) {
69 GRExprEngine& Eng = BR.getEngine();
70 GenericEmitWarnings(BR, *this, Eng.null_derefs_begin(),
71 Eng.null_derefs_end());
72 }
73};
74
75class VISIBILITY_HIDDEN UndefDeref : public BugType {
76public:
77 virtual const char* getName() const {
78 return "bad dereference";
79 }
80
81 virtual const char* getDescription() const {
82 return "Dereference of undefined value.";
83 }
84
85 virtual void EmitWarnings(BugReporter& BR) {
86 GRExprEngine& Eng = BR.getEngine();
87 GenericEmitWarnings(BR, *this, Eng.undef_derefs_begin(),
88 Eng.undef_derefs_end());
89 }
90};
91
92class VISIBILITY_HIDDEN UndefBranch : public BugType {
93public:
94 virtual const char* getName() const {
95 return "uninitialized value";
96 }
97
98 virtual const char* getDescription() const {
99 return "Branch condition evaluates to an uninitialized value.";
100 }
101
102 virtual void EmitWarnings(BugReporter& BR) {
103 GRExprEngine& Eng = BR.getEngine();
104 GenericEmitWarnings(BR, *this, Eng.undef_branches_begin(),
105 Eng.undef_branches_end());
106 }
107};
108
109class VISIBILITY_HIDDEN DivZero : public BugType {
110public:
111 virtual const char* getName() const {
112 return "divide-by-zero";
113 }
114
115 virtual const char* getDescription() const {
116 return "Division by zero/undefined value.";
117 }
118
119 virtual void EmitWarnings(BugReporter& BR) {
120 GRExprEngine& Eng = BR.getEngine();
121 GenericEmitWarnings(BR, *this, Eng.explicit_bad_divides_begin(),
122 Eng.explicit_bad_divides_end());
123 }
124};
125
126class VISIBILITY_HIDDEN UndefResult : public BugType {
127public:
128 virtual const char* getName() const {
129 return "undefined result";
130 }
131
132 virtual const char* getDescription() const {
133 return "Result of operation is undefined.";
134 }
135
136 virtual void EmitWarnings(BugReporter& BR) {
137 GRExprEngine& Eng = BR.getEngine();
138 GenericEmitWarnings(BR, *this, Eng.undef_results_begin(),
Ted Kremenek4d35dac2008-04-10 16:05:13 +0000139 Eng.undef_results_end());
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000140 }
141};
142
143class VISIBILITY_HIDDEN BadCall : public BugType {
144public:
145 virtual const char* getName() const {
146 return "invalid function call";
147 }
148
149 virtual const char* getDescription() const {
150 return "Called function is a NULL or undefined function pointer value.";
151 }
152
153 virtual void EmitWarnings(BugReporter& BR) {
154 GRExprEngine& Eng = BR.getEngine();
155 GenericEmitWarnings(BR, *this, Eng.bad_calls_begin(),
Ted Kremenek4d35dac2008-04-10 16:05:13 +0000156 Eng.bad_calls_end());
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000157 }
158};
159
160
161class VISIBILITY_HIDDEN BadArg : public BugType {
162protected:
163
164 class Report : public BugReport {
165 const SourceRange R;
166 public:
167 Report(BugType& D, Expr* E) : BugReport(D), R(E->getSourceRange()) {}
168 virtual ~Report() {}
169
170 virtual void getRanges(const SourceRange*& B, const SourceRange*& E) const {
171 B = &R;
172 E = B+1;
173 }
174 };
175
176public:
177
178 virtual ~BadArg() {}
179
180 virtual const char* getName() const {
181 return "bad argument";
182 }
183
184 virtual const char* getDescription() const {
185 return "Pass-by-value argument in function is undefined.";
186 }
187
188 virtual void EmitWarnings(BugReporter& BR) {
189 GRExprEngine& Eng = BR.getEngine();
190
191 for (GRExprEngine::UndefArgsTy::iterator I = Eng.undef_arg_begin(),
192 E = Eng.undef_arg_end(); I!=E; ++I) {
193
194 // Generate a report for this bug.
195 Report report(*this, I->second);
196
197 // Emit the warning.
198 BR.EmitPathWarning(report, I->first);
199 }
200
201 }
202};
203
204class VISIBILITY_HIDDEN BadMsgExprArg : public BadArg {
205public:
206 virtual const char* getName() const {
207 return "bad argument";
208 }
209
210 virtual const char* getDescription() const {
211 return "Pass-by-value argument in message expression is undefined.";
212 }
213
214 virtual void EmitWarnings(BugReporter& BR) {
215 GRExprEngine& Eng = BR.getEngine();
216
217 for (GRExprEngine::UndefArgsTy::iterator I=Eng.msg_expr_undef_arg_begin(),
Ted Kremenek4d35dac2008-04-10 16:05:13 +0000218 E = Eng.msg_expr_undef_arg_end(); I!=E; ++I) {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000219
220 // Generate a report for this bug.
221 Report report(*this, I->second);
222
223 // Emit the warning.
224 BR.EmitPathWarning(report, I->first);
225 }
226
227 }
228};
229
230class VISIBILITY_HIDDEN BadReceiver : public BugType {
231
232 class Report : public BugReport {
233 SourceRange R;
234 public:
235 Report(BugType& D, ExplodedNode<ValueState> *N) : BugReport(D) {
236 Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
237 Expr* E = cast<ObjCMessageExpr>(S)->getReceiver();
238 assert (E && "Receiver cannot be NULL");
239 R = E->getSourceRange();
240 }
241
242 virtual ~Report() {}
243
244 virtual void getRanges(const SourceRange*& B, const SourceRange*& E) const {
245 B = &R;
246 E = B+1;
247 }
248 };
249
250public:
251 virtual const char* getName() const {
252 return "bad receiver";
253 }
254
255 virtual const char* getDescription() const {
256 return "Receiver in message expression is an uninitialized value.";
257 }
258
259 virtual void EmitWarnings(BugReporter& BR) {
260 GRExprEngine& Eng = BR.getEngine();
261
262 for (GRExprEngine::UndefReceiversTy::iterator I=Eng.undef_receivers_begin(),
263 E = Eng.undef_receivers_end(); I!=E; ++I) {
264
265 // Generate a report for this bug.
266 Report report(*this, *I);
267
268 // Emit the warning.
269 BR.EmitPathWarning(report, *I);
270 }
271 }
272};
273
274class VISIBILITY_HIDDEN RetStack : public BugType {
275public:
276 virtual const char* getName() const {
277 return "return of stack address";
278 }
279
280 virtual const char* getDescription() const {
281 return "Address of stack-allocated variable returned.";
282 }
283
284 virtual void EmitWarnings(BugReporter& BR) {
285 GRExprEngine& Eng = BR.getEngine();
286 GenericEmitWarnings(BR, *this, Eng.ret_stackaddr_begin(),
Ted Kremenek4d35dac2008-04-10 16:05:13 +0000287 Eng.ret_stackaddr_end());
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000288 }
289};
290
291} // end anonymous namespace
292
293void GRSimpleVals::RegisterChecks(GRExprEngine& Eng) {
294 Eng.Register(new NullDeref());
295 Eng.Register(new UndefDeref());
296 Eng.Register(new UndefBranch());
297 Eng.Register(new DivZero());
298 Eng.Register(new UndefResult());
299 Eng.Register(new BadCall());
300 Eng.Register(new RetStack());
301 Eng.Register(new BadArg());
302 Eng.Register(new BadMsgExprArg());
303 Eng.Register(new BadReceiver());
304
305 // Add extra checkers.
306
307 GRSimpleAPICheck* FoundationCheck =
308 CreateBasicObjCFoundationChecks(Eng.getContext(), &Eng.getStateManager());
309
310 Eng.AddObjCMessageExprCheck(FoundationCheck);
311}
312
Ted Kremenekdd598112008-04-02 07:05:46 +0000313//===----------------------------------------------------------------------===//
Ted Kremenekd71ed262008-04-10 22:16:52 +0000314// Transfer Function creation for External clients.
Ted Kremenek503d6132008-04-02 05:15:22 +0000315//===----------------------------------------------------------------------===//
Ted Kremenek61f3e052008-04-03 04:42:52 +0000316
Ted Kremenekd71ed262008-04-10 22:16:52 +0000317GRTransferFuncs* clang::MakeGRSimpleValsTF() { return new GRSimpleVals(); }
Ted Kremeneke01c9872008-02-14 22:36:46 +0000318
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000319//===----------------------------------------------------------------------===//
320// Transfer function for Casts.
321//===----------------------------------------------------------------------===//
322
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000323RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, NonLVal X, QualType T) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000324
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000325 if (!isa<nonlval::ConcreteInt>(X))
326 return UnknownVal();
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000327
328 BasicValueFactory& BasicVals = Eng.getBasicVals();
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000329
330 llvm::APSInt V = cast<nonlval::ConcreteInt>(X).getValue();
Ted Kremenek1b9df4c2008-03-14 18:14:50 +0000331 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType()
332 || T->isObjCQualifiedIdType());
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000333 V.extOrTrunc(Eng.getContext().getTypeSize(T));
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000334
Ted Kremenek9ef1ec92008-02-21 18:43:30 +0000335 if (T->isPointerType())
Ted Kremenek240f1f02008-03-07 20:13:31 +0000336 return lval::ConcreteInt(BasicVals.getValue(V));
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000337 else
Ted Kremenek240f1f02008-03-07 20:13:31 +0000338 return nonlval::ConcreteInt(BasicVals.getValue(V));
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000339}
340
341// Casts.
342
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000343RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, LVal X, QualType T) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000344
Chris Lattner423a3c92008-04-02 17:45:06 +0000345 if (T->isPointerLikeType() || T->isObjCQualifiedIdType())
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000346 return X;
347
Ted Kremenek9ef1ec92008-02-21 18:43:30 +0000348 assert (T->isIntegerType());
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000349
350 if (!isa<lval::ConcreteInt>(X))
351 return UnknownVal();
352
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000353 BasicValueFactory& BasicVals = Eng.getBasicVals();
354
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000355 llvm::APSInt V = cast<lval::ConcreteInt>(X).getValue();
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000356 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000357 V.extOrTrunc(Eng.getContext().getTypeSize(T));
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000358
Ted Kremenek240f1f02008-03-07 20:13:31 +0000359 return nonlval::ConcreteInt(BasicVals.getValue(V));
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000360}
361
362// Unary operators.
363
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000364RVal GRSimpleVals::EvalMinus(GRExprEngine& Eng, UnaryOperator* U, NonLVal X){
Ted Kremenek692416c2008-02-18 22:57:02 +0000365
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000366 switch (X.getSubKind()) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000367
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000368 case nonlval::ConcreteIntKind:
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000369 return cast<nonlval::ConcreteInt>(X).EvalMinus(Eng.getBasicVals(), U);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000370
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000371 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000372 return UnknownVal();
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000373 }
374}
375
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000376RVal GRSimpleVals::EvalComplement(GRExprEngine& Eng, NonLVal X) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000377
Ted Kremenek90e42032008-02-20 04:12:31 +0000378 switch (X.getSubKind()) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000379
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000380 case nonlval::ConcreteIntKind:
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000381 return cast<nonlval::ConcreteInt>(X).EvalComplement(Eng.getBasicVals());
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000382
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000383 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000384 return UnknownVal();
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000385 }
386}
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000387
388// Binary operators.
389
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000390RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
391 NonLVal L, NonLVal R) {
392
393 BasicValueFactory& BasicVals = Eng.getBasicVals();
394
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000395 while (1) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000396
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000397 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000398 default:
Ted Kremenek9258a642008-02-21 19:10:12 +0000399 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000400
401 case nonlval::ConcreteIntKind:
402
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000403 if (isa<nonlval::ConcreteInt>(R)) {
404 const nonlval::ConcreteInt& L_CI = cast<nonlval::ConcreteInt>(L);
405 const nonlval::ConcreteInt& R_CI = cast<nonlval::ConcreteInt>(R);
Ted Kremenek240f1f02008-03-07 20:13:31 +0000406 return L_CI.EvalBinOp(BasicVals, Op, R_CI);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000407 }
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000408 else {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000409 NonLVal tmp = R;
410 R = L;
411 L = tmp;
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000412 continue;
413 }
414
415 case nonlval::SymbolValKind: {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000416
417 if (isa<nonlval::ConcreteInt>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000418 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000419 BasicVals.getConstraint(cast<nonlval::SymbolVal>(L).getSymbol(), Op,
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000420 cast<nonlval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000421
422 return nonlval::SymIntConstraintVal(C);
423 }
424 else
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000425 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000426 }
427 }
428 }
429}
430
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000431
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000432// Binary Operators (except assignments and comma).
433
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000434RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000435 LVal L, LVal R) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000436
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000437 switch (Op) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000438
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000439 default:
440 return UnknownVal();
441
442 case BinaryOperator::EQ:
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000443 return EvalEQ(Eng, L, R);
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000444
445 case BinaryOperator::NE:
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000446 return EvalNE(Eng, L, R);
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000447 }
448}
449
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000450// Pointer arithmetic.
451
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000452RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000453 LVal L, NonLVal R) {
454 return UnknownVal();
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000455}
456
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000457// Equality operators for LVals.
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000458
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000459RVal GRSimpleVals::EvalEQ(GRExprEngine& Eng, LVal L, LVal R) {
460
461 BasicValueFactory& BasicVals = Eng.getBasicVals();
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000462
463 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000464
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000465 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000466 assert(false && "EQ not implemented for this LVal.");
467 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000468
469 case lval::ConcreteIntKind:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000470
471 if (isa<lval::ConcreteInt>(R)) {
472 bool b = cast<lval::ConcreteInt>(L).getValue() ==
473 cast<lval::ConcreteInt>(R).getValue();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000474
Ted Kremenek240f1f02008-03-07 20:13:31 +0000475 return NonLVal::MakeIntTruthVal(BasicVals, b);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000476 }
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000477 else if (isa<lval::SymbolVal>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000478
479 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000480 BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000481 BinaryOperator::EQ,
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000482 cast<lval::ConcreteInt>(L).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000483
484 return nonlval::SymIntConstraintVal(C);
485 }
486
487 break;
488
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000489 case lval::SymbolValKind: {
490
491 if (isa<lval::ConcreteInt>(R)) {
492 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000493 BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000494 BinaryOperator::EQ,
495 cast<lval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000496
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000497 return nonlval::SymIntConstraintVal(C);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000498 }
499
Ted Kremenekf700df22008-02-22 18:41:59 +0000500 // FIXME: Implement == for lval Symbols. This is mainly useful
501 // in iterator loops when traversing a buffer, e.g. while(z != zTerm).
502 // Since this is not useful for many checkers we'll punt on this for
503 // now.
504
505 return UnknownVal();
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000506 }
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000507
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000508 case lval::DeclValKind:
Ted Kremenekdc3936b2008-02-22 00:54:56 +0000509 case lval::FuncValKind:
510 case lval::GotoLabelKind:
Ted Kremenek240f1f02008-03-07 20:13:31 +0000511 return NonLVal::MakeIntTruthVal(BasicVals, L == R);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000512 }
513
Ted Kremenek240f1f02008-03-07 20:13:31 +0000514 return NonLVal::MakeIntTruthVal(BasicVals, false);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000515}
516
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000517RVal GRSimpleVals::EvalNE(GRExprEngine& Eng, LVal L, LVal R) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000518
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000519 BasicValueFactory& BasicVals = Eng.getBasicVals();
520
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000521 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000522
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000523 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000524 assert(false && "NE not implemented for this LVal.");
525 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000526
527 case lval::ConcreteIntKind:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000528
529 if (isa<lval::ConcreteInt>(R)) {
530 bool b = cast<lval::ConcreteInt>(L).getValue() !=
531 cast<lval::ConcreteInt>(R).getValue();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000532
Ted Kremenek240f1f02008-03-07 20:13:31 +0000533 return NonLVal::MakeIntTruthVal(BasicVals, b);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000534 }
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000535 else if (isa<lval::SymbolVal>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000536 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000537 BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000538 BinaryOperator::NE,
539 cast<lval::ConcreteInt>(L).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000540
541 return nonlval::SymIntConstraintVal(C);
542 }
543
544 break;
545
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000546 case lval::SymbolValKind: {
547 if (isa<lval::ConcreteInt>(R)) {
548 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000549 BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000550 BinaryOperator::NE,
551 cast<lval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000552
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000553 return nonlval::SymIntConstraintVal(C);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000554 }
555
Ted Kremenekf700df22008-02-22 18:41:59 +0000556 // FIXME: Implement != for lval Symbols. This is mainly useful
557 // in iterator loops when traversing a buffer, e.g. while(z != zTerm).
558 // Since this is not useful for many checkers we'll punt on this for
559 // now.
560
561 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000562
563 break;
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000564 }
565
566 case lval::DeclValKind:
Ted Kremenekdc3936b2008-02-22 00:54:56 +0000567 case lval::FuncValKind:
568 case lval::GotoLabelKind:
Ted Kremenek240f1f02008-03-07 20:13:31 +0000569 return NonLVal::MakeIntTruthVal(BasicVals, L != R);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000570 }
571
Ted Kremenek240f1f02008-03-07 20:13:31 +0000572 return NonLVal::MakeIntTruthVal(BasicVals, true);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000573}
Ted Kremenek06747692008-02-26 23:04:29 +0000574
575//===----------------------------------------------------------------------===//
576// Transfer function for Function Calls.
577//===----------------------------------------------------------------------===//
578
Ted Kremenek330dddd2008-03-05 00:33:14 +0000579void GRSimpleVals::EvalCall(ExplodedNodeSet<ValueState>& Dst,
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000580 GRExprEngine& Eng,
Ted Kremenek330dddd2008-03-05 00:33:14 +0000581 GRStmtNodeBuilder<ValueState>& Builder,
Ted Kremenek330dddd2008-03-05 00:33:14 +0000582 CallExpr* CE, LVal L,
583 ExplodedNode<ValueState>* Pred) {
584
Ted Kremenekf923a912008-03-12 21:04:07 +0000585 ValueStateManager& StateMgr = Eng.getStateManager();
586 ValueState* St = Builder.GetState(Pred);
Ted Kremenek06747692008-02-26 23:04:29 +0000587
588 // Invalidate all arguments passed in by reference (LVals).
589
590 for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
591 I != E; ++I) {
592
Ted Kremenekf923a912008-03-12 21:04:07 +0000593 RVal V = StateMgr.GetRVal(St, *I);
Ted Kremenek06747692008-02-26 23:04:29 +0000594
595 if (isa<LVal>(V))
Ted Kremenekf923a912008-03-12 21:04:07 +0000596 St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
Ted Kremenek06747692008-02-26 23:04:29 +0000597 }
Ted Kremenekf923a912008-03-12 21:04:07 +0000598
599 // Make up a symbol for the return value of this function.
600
601 if (CE->getType() != Eng.getContext().VoidTy) {
602 unsigned Count = Builder.getCurrentBlockCount();
Ted Kremenek361fa8e2008-03-12 21:45:47 +0000603 SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(CE, Count);
Ted Kremenekf923a912008-03-12 21:04:07 +0000604
605 RVal X = CE->getType()->isPointerType()
606 ? cast<RVal>(lval::SymbolVal(Sym))
607 : cast<RVal>(nonlval::SymbolVal(Sym));
608
609 St = StateMgr.SetRVal(St, CE, X, Eng.getCFG().isBlkExpr(CE), false);
610 }
Ted Kremenek330dddd2008-03-05 00:33:14 +0000611
Ted Kremenek0e561a32008-03-21 21:30:14 +0000612 Builder.MakeNode(Dst, CE, Pred, St);
Ted Kremenek06747692008-02-26 23:04:29 +0000613}