blob: e41df7662c212c9114d05102b348fa420cece0ab [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>
Ted Kremenek95cc1ba2008-04-18 20:54:29 +000043void GenericEmitWarnings(BugReporter& BR, BugType& D, ITER I, ITER E) {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +000044
45 for (; I != E; ++I) {
Ted Kremenekd2f642b2008-04-14 17:39:48 +000046 BugReport R(D, GetNode(I));
Ted Kremenek75840e12008-04-18 01:56:37 +000047 BR.EmitWarning(R);
Ted Kremenek50a6d0c2008-04-09 21:41:14 +000048 }
49}
50
51//===----------------------------------------------------------------------===//
52// Bug Descriptions.
53//===----------------------------------------------------------------------===//
54
55namespace {
56
Ted Kremenek95cc1ba2008-04-18 20:54:29 +000057class VISIBILITY_HIDDEN NullDeref : public BugTypeCacheLocation {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +000058public:
59 virtual const char* getName() const {
60 return "null dereference";
61 }
62
63 virtual const char* getDescription() const {
64 return "Dereference of null pointer.";
65 }
66
67 virtual void EmitWarnings(BugReporter& BR) {
68 GRExprEngine& Eng = BR.getEngine();
69 GenericEmitWarnings(BR, *this, Eng.null_derefs_begin(),
70 Eng.null_derefs_end());
71 }
72};
73
Ted Kremenek95cc1ba2008-04-18 20:54:29 +000074class VISIBILITY_HIDDEN UndefDeref : public BugTypeCacheLocation {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +000075public:
76 virtual const char* getName() const {
77 return "bad dereference";
78 }
79
80 virtual const char* getDescription() const {
81 return "Dereference of undefined value.";
82 }
83
84 virtual void EmitWarnings(BugReporter& BR) {
85 GRExprEngine& Eng = BR.getEngine();
86 GenericEmitWarnings(BR, *this, Eng.undef_derefs_begin(),
87 Eng.undef_derefs_end());
88 }
89};
90
Ted Kremenek95cc1ba2008-04-18 20:54:29 +000091class VISIBILITY_HIDDEN UndefBranch : public BugTypeCacheLocation {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +000092public:
93 virtual const char* getName() const {
94 return "uninitialized value";
95 }
96
97 virtual const char* getDescription() const {
98 return "Branch condition evaluates to an uninitialized value.";
99 }
100
101 virtual void EmitWarnings(BugReporter& BR) {
102 GRExprEngine& Eng = BR.getEngine();
103 GenericEmitWarnings(BR, *this, Eng.undef_branches_begin(),
104 Eng.undef_branches_end());
105 }
106};
107
Ted Kremenek95cc1ba2008-04-18 20:54:29 +0000108class VISIBILITY_HIDDEN DivZero : public BugTypeCacheLocation {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000109public:
110 virtual const char* getName() const {
111 return "divide-by-zero";
112 }
113
114 virtual const char* getDescription() const {
115 return "Division by zero/undefined value.";
116 }
117
118 virtual void EmitWarnings(BugReporter& BR) {
119 GRExprEngine& Eng = BR.getEngine();
120 GenericEmitWarnings(BR, *this, Eng.explicit_bad_divides_begin(),
121 Eng.explicit_bad_divides_end());
122 }
123};
124
Ted Kremenek95cc1ba2008-04-18 20:54:29 +0000125class VISIBILITY_HIDDEN UndefResult : public BugTypeCacheLocation {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000126public:
127 virtual const char* getName() const {
128 return "undefined result";
129 }
130
131 virtual const char* getDescription() const {
132 return "Result of operation is undefined.";
133 }
134
135 virtual void EmitWarnings(BugReporter& BR) {
136 GRExprEngine& Eng = BR.getEngine();
137 GenericEmitWarnings(BR, *this, Eng.undef_results_begin(),
Ted Kremenek4d35dac2008-04-10 16:05:13 +0000138 Eng.undef_results_end());
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000139 }
140};
141
Ted Kremenek95cc1ba2008-04-18 20:54:29 +0000142class VISIBILITY_HIDDEN BadCall : public BugTypeCacheLocation {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000143public:
144 virtual const char* getName() const {
145 return "invalid function call";
146 }
147
148 virtual const char* getDescription() const {
149 return "Called function is a NULL or undefined function pointer value.";
150 }
151
152 virtual void EmitWarnings(BugReporter& BR) {
153 GRExprEngine& Eng = BR.getEngine();
154 GenericEmitWarnings(BR, *this, Eng.bad_calls_begin(),
Ted Kremenek4d35dac2008-04-10 16:05:13 +0000155 Eng.bad_calls_end());
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000156 }
157};
158
159
Ted Kremenek95cc1ba2008-04-18 20:54:29 +0000160class VISIBILITY_HIDDEN BadArg : public BugTypeCacheLocation {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000161public:
162
163 virtual ~BadArg() {}
164
165 virtual const char* getName() const {
166 return "bad argument";
167 }
168
169 virtual const char* getDescription() const {
170 return "Pass-by-value argument in function is undefined.";
171 }
172
173 virtual void EmitWarnings(BugReporter& BR) {
174 GRExprEngine& Eng = BR.getEngine();
175
176 for (GRExprEngine::UndefArgsTy::iterator I = Eng.undef_arg_begin(),
177 E = Eng.undef_arg_end(); I!=E; ++I) {
178
179 // Generate a report for this bug.
Ted Kremenekd2f642b2008-04-14 17:39:48 +0000180 RangedBugReport report(*this, I->first);
181 report.addRange(I->second->getSourceRange());
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000182
183 // Emit the warning.
Ted Kremenek75840e12008-04-18 01:56:37 +0000184 BR.EmitWarning(report);
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000185 }
186
187 }
188};
189
190class VISIBILITY_HIDDEN BadMsgExprArg : public BadArg {
191public:
192 virtual const char* getName() const {
193 return "bad argument";
194 }
195
196 virtual const char* getDescription() const {
197 return "Pass-by-value argument in message expression is undefined.";
198 }
199
200 virtual void EmitWarnings(BugReporter& BR) {
201 GRExprEngine& Eng = BR.getEngine();
202
203 for (GRExprEngine::UndefArgsTy::iterator I=Eng.msg_expr_undef_arg_begin(),
Ted Kremenek4d35dac2008-04-10 16:05:13 +0000204 E = Eng.msg_expr_undef_arg_end(); I!=E; ++I) {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000205
206 // Generate a report for this bug.
Ted Kremenekd2f642b2008-04-14 17:39:48 +0000207 RangedBugReport report(*this, I->first);
208 report.addRange(I->second->getSourceRange());
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000209
210 // Emit the warning.
Ted Kremenek75840e12008-04-18 01:56:37 +0000211 BR.EmitWarning(report);
Ted Kremenekd2f642b2008-04-14 17:39:48 +0000212 }
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000213 }
214};
215
Ted Kremenek95cc1ba2008-04-18 20:54:29 +0000216class VISIBILITY_HIDDEN BadReceiver : public BugTypeCacheLocation {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000217public:
218 virtual const char* getName() const {
219 return "bad receiver";
220 }
221
222 virtual const char* getDescription() const {
223 return "Receiver in message expression is an uninitialized value.";
224 }
225
226 virtual void EmitWarnings(BugReporter& BR) {
227 GRExprEngine& Eng = BR.getEngine();
228
229 for (GRExprEngine::UndefReceiversTy::iterator I=Eng.undef_receivers_begin(),
Argyrios Kyrtzidisafe10912008-04-15 16:30:10 +0000230 End = Eng.undef_receivers_end(); I!=End; ++I) {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000231
232 // Generate a report for this bug.
Ted Kremenekd2f642b2008-04-14 17:39:48 +0000233 RangedBugReport report(*this, *I);
234
235 ExplodedNode<ValueState>* N = *I;
236 Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
237 Expr* E = cast<ObjCMessageExpr>(S)->getReceiver();
238 assert (E && "Receiver cannot be NULL");
239 report.addRange(E->getSourceRange());
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000240
241 // Emit the warning.
Ted Kremenek75840e12008-04-18 01:56:37 +0000242 BR.EmitWarning(report);
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000243 }
244 }
245};
246
Ted Kremenek95cc1ba2008-04-18 20:54:29 +0000247class VISIBILITY_HIDDEN RetStack : public BugTypeCacheLocation {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000248public:
249 virtual const char* getName() const {
250 return "return of stack address";
251 }
252
253 virtual const char* getDescription() const {
254 return "Address of stack-allocated variable returned.";
255 }
256
257 virtual void EmitWarnings(BugReporter& BR) {
258 GRExprEngine& Eng = BR.getEngine();
259 GenericEmitWarnings(BR, *this, Eng.ret_stackaddr_begin(),
Ted Kremenek4d35dac2008-04-10 16:05:13 +0000260 Eng.ret_stackaddr_end());
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000261 }
262};
263
264} // end anonymous namespace
265
266void GRSimpleVals::RegisterChecks(GRExprEngine& Eng) {
Ted Kremenekd2f642b2008-04-14 17:39:48 +0000267
268 // Path-sensitive checks.
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000269 Eng.Register(new NullDeref());
270 Eng.Register(new UndefDeref());
271 Eng.Register(new UndefBranch());
272 Eng.Register(new DivZero());
273 Eng.Register(new UndefResult());
274 Eng.Register(new BadCall());
275 Eng.Register(new RetStack());
276 Eng.Register(new BadArg());
277 Eng.Register(new BadMsgExprArg());
278 Eng.Register(new BadReceiver());
279
Ted Kremenekd2f642b2008-04-14 17:39:48 +0000280 // Flow-sensitive checks.
281 Eng.Register(MakeDeadStoresChecker());
282
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000283 // Add extra checkers.
284
285 GRSimpleAPICheck* FoundationCheck =
286 CreateBasicObjCFoundationChecks(Eng.getContext(), &Eng.getStateManager());
287
288 Eng.AddObjCMessageExprCheck(FoundationCheck);
289}
290
Ted Kremenekdd598112008-04-02 07:05:46 +0000291//===----------------------------------------------------------------------===//
Ted Kremenekd71ed262008-04-10 22:16:52 +0000292// Transfer Function creation for External clients.
Ted Kremenek503d6132008-04-02 05:15:22 +0000293//===----------------------------------------------------------------------===//
Ted Kremenek61f3e052008-04-03 04:42:52 +0000294
Ted Kremenekd71ed262008-04-10 22:16:52 +0000295GRTransferFuncs* clang::MakeGRSimpleValsTF() { return new GRSimpleVals(); }
Ted Kremeneke01c9872008-02-14 22:36:46 +0000296
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000297//===----------------------------------------------------------------------===//
298// Transfer function for Casts.
299//===----------------------------------------------------------------------===//
300
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000301RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, NonLVal X, QualType T) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000302
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000303 if (!isa<nonlval::ConcreteInt>(X))
304 return UnknownVal();
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000305
306 BasicValueFactory& BasicVals = Eng.getBasicVals();
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000307
308 llvm::APSInt V = cast<nonlval::ConcreteInt>(X).getValue();
Ted Kremenek1b9df4c2008-03-14 18:14:50 +0000309 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType()
310 || T->isObjCQualifiedIdType());
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000311 V.extOrTrunc(Eng.getContext().getTypeSize(T));
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000312
Ted Kremenek9ef1ec92008-02-21 18:43:30 +0000313 if (T->isPointerType())
Ted Kremenek240f1f02008-03-07 20:13:31 +0000314 return lval::ConcreteInt(BasicVals.getValue(V));
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000315 else
Ted Kremenek240f1f02008-03-07 20:13:31 +0000316 return nonlval::ConcreteInt(BasicVals.getValue(V));
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000317}
318
319// Casts.
320
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000321RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, LVal X, QualType T) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000322
Chris Lattner423a3c92008-04-02 17:45:06 +0000323 if (T->isPointerLikeType() || T->isObjCQualifiedIdType())
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000324 return X;
325
Ted Kremenek9ef1ec92008-02-21 18:43:30 +0000326 assert (T->isIntegerType());
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000327
328 if (!isa<lval::ConcreteInt>(X))
329 return UnknownVal();
330
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000331 BasicValueFactory& BasicVals = Eng.getBasicVals();
332
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000333 llvm::APSInt V = cast<lval::ConcreteInt>(X).getValue();
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000334 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000335 V.extOrTrunc(Eng.getContext().getTypeSize(T));
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000336
Ted Kremenek240f1f02008-03-07 20:13:31 +0000337 return nonlval::ConcreteInt(BasicVals.getValue(V));
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000338}
339
340// Unary operators.
341
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000342RVal GRSimpleVals::EvalMinus(GRExprEngine& Eng, UnaryOperator* U, NonLVal X){
Ted Kremenek692416c2008-02-18 22:57:02 +0000343
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000344 switch (X.getSubKind()) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000345
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000346 case nonlval::ConcreteIntKind:
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000347 return cast<nonlval::ConcreteInt>(X).EvalMinus(Eng.getBasicVals(), U);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000348
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000349 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000350 return UnknownVal();
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000351 }
352}
353
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000354RVal GRSimpleVals::EvalComplement(GRExprEngine& Eng, NonLVal X) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000355
Ted Kremenek90e42032008-02-20 04:12:31 +0000356 switch (X.getSubKind()) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000357
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000358 case nonlval::ConcreteIntKind:
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000359 return cast<nonlval::ConcreteInt>(X).EvalComplement(Eng.getBasicVals());
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000360
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000361 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000362 return UnknownVal();
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000363 }
364}
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000365
366// Binary operators.
367
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000368RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
369 NonLVal L, NonLVal R) {
370
371 BasicValueFactory& BasicVals = Eng.getBasicVals();
372
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000373 while (1) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000374
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000375 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000376 default:
Ted Kremenek9258a642008-02-21 19:10:12 +0000377 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000378
379 case nonlval::ConcreteIntKind:
380
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000381 if (isa<nonlval::ConcreteInt>(R)) {
382 const nonlval::ConcreteInt& L_CI = cast<nonlval::ConcreteInt>(L);
383 const nonlval::ConcreteInt& R_CI = cast<nonlval::ConcreteInt>(R);
Ted Kremenek240f1f02008-03-07 20:13:31 +0000384 return L_CI.EvalBinOp(BasicVals, Op, R_CI);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000385 }
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000386 else {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000387 NonLVal tmp = R;
388 R = L;
389 L = tmp;
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000390 continue;
391 }
392
393 case nonlval::SymbolValKind: {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000394
395 if (isa<nonlval::ConcreteInt>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000396 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000397 BasicVals.getConstraint(cast<nonlval::SymbolVal>(L).getSymbol(), Op,
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000398 cast<nonlval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000399
400 return nonlval::SymIntConstraintVal(C);
401 }
402 else
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000403 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000404 }
405 }
406 }
407}
408
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000409
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000410// Binary Operators (except assignments and comma).
411
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000412RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000413 LVal L, LVal R) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000414
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000415 switch (Op) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000416
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000417 default:
418 return UnknownVal();
419
420 case BinaryOperator::EQ:
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000421 return EvalEQ(Eng, L, R);
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000422
423 case BinaryOperator::NE:
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000424 return EvalNE(Eng, L, R);
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000425 }
426}
427
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000428// Pointer arithmetic.
429
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000430RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000431 LVal L, NonLVal R) {
432 return UnknownVal();
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000433}
434
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000435// Equality operators for LVals.
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000436
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000437RVal GRSimpleVals::EvalEQ(GRExprEngine& Eng, LVal L, LVal R) {
438
439 BasicValueFactory& BasicVals = Eng.getBasicVals();
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000440
441 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000442
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000443 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000444 assert(false && "EQ not implemented for this LVal.");
445 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000446
447 case lval::ConcreteIntKind:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000448
449 if (isa<lval::ConcreteInt>(R)) {
450 bool b = cast<lval::ConcreteInt>(L).getValue() ==
451 cast<lval::ConcreteInt>(R).getValue();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000452
Ted Kremenek240f1f02008-03-07 20:13:31 +0000453 return NonLVal::MakeIntTruthVal(BasicVals, b);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000454 }
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000455 else if (isa<lval::SymbolVal>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000456
457 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000458 BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000459 BinaryOperator::EQ,
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000460 cast<lval::ConcreteInt>(L).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000461
462 return nonlval::SymIntConstraintVal(C);
463 }
464
465 break;
466
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000467 case lval::SymbolValKind: {
468
469 if (isa<lval::ConcreteInt>(R)) {
470 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000471 BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000472 BinaryOperator::EQ,
473 cast<lval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000474
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000475 return nonlval::SymIntConstraintVal(C);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000476 }
477
Ted Kremenekf700df22008-02-22 18:41:59 +0000478 // FIXME: Implement == for lval Symbols. This is mainly useful
479 // in iterator loops when traversing a buffer, e.g. while(z != zTerm).
480 // Since this is not useful for many checkers we'll punt on this for
481 // now.
482
483 return UnknownVal();
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000484 }
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000485
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000486 case lval::DeclValKind:
Ted Kremenekdc3936b2008-02-22 00:54:56 +0000487 case lval::FuncValKind:
488 case lval::GotoLabelKind:
Ted Kremenek240f1f02008-03-07 20:13:31 +0000489 return NonLVal::MakeIntTruthVal(BasicVals, L == R);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000490 }
491
Ted Kremenek240f1f02008-03-07 20:13:31 +0000492 return NonLVal::MakeIntTruthVal(BasicVals, false);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000493}
494
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000495RVal GRSimpleVals::EvalNE(GRExprEngine& Eng, LVal L, LVal R) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000496
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000497 BasicValueFactory& BasicVals = Eng.getBasicVals();
498
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000499 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000500
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000501 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000502 assert(false && "NE not implemented for this LVal.");
503 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000504
505 case lval::ConcreteIntKind:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000506
507 if (isa<lval::ConcreteInt>(R)) {
508 bool b = cast<lval::ConcreteInt>(L).getValue() !=
509 cast<lval::ConcreteInt>(R).getValue();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000510
Ted Kremenek240f1f02008-03-07 20:13:31 +0000511 return NonLVal::MakeIntTruthVal(BasicVals, b);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000512 }
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000513 else if (isa<lval::SymbolVal>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000514 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000515 BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000516 BinaryOperator::NE,
517 cast<lval::ConcreteInt>(L).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000518
519 return nonlval::SymIntConstraintVal(C);
520 }
521
522 break;
523
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000524 case lval::SymbolValKind: {
525 if (isa<lval::ConcreteInt>(R)) {
526 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000527 BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000528 BinaryOperator::NE,
529 cast<lval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000530
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000531 return nonlval::SymIntConstraintVal(C);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000532 }
533
Ted Kremenekf700df22008-02-22 18:41:59 +0000534 // FIXME: Implement != for lval Symbols. This is mainly useful
535 // in iterator loops when traversing a buffer, e.g. while(z != zTerm).
536 // Since this is not useful for many checkers we'll punt on this for
537 // now.
538
539 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000540
541 break;
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000542 }
543
544 case lval::DeclValKind:
Ted Kremenekdc3936b2008-02-22 00:54:56 +0000545 case lval::FuncValKind:
546 case lval::GotoLabelKind:
Ted Kremenek240f1f02008-03-07 20:13:31 +0000547 return NonLVal::MakeIntTruthVal(BasicVals, L != R);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000548 }
549
Ted Kremenek240f1f02008-03-07 20:13:31 +0000550 return NonLVal::MakeIntTruthVal(BasicVals, true);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000551}
Ted Kremenek06747692008-02-26 23:04:29 +0000552
553//===----------------------------------------------------------------------===//
Ted Kremeneke695e1c2008-04-15 23:06:53 +0000554// Transfer function for function calls.
Ted Kremenek06747692008-02-26 23:04:29 +0000555//===----------------------------------------------------------------------===//
556
Ted Kremenek330dddd2008-03-05 00:33:14 +0000557void GRSimpleVals::EvalCall(ExplodedNodeSet<ValueState>& Dst,
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000558 GRExprEngine& Eng,
Ted Kremenek330dddd2008-03-05 00:33:14 +0000559 GRStmtNodeBuilder<ValueState>& Builder,
Ted Kremenek330dddd2008-03-05 00:33:14 +0000560 CallExpr* CE, LVal L,
561 ExplodedNode<ValueState>* Pred) {
562
Ted Kremenekf923a912008-03-12 21:04:07 +0000563 ValueStateManager& StateMgr = Eng.getStateManager();
564 ValueState* St = Builder.GetState(Pred);
Ted Kremenek06747692008-02-26 23:04:29 +0000565
566 // Invalidate all arguments passed in by reference (LVals).
567
568 for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
569 I != E; ++I) {
570
Ted Kremenekf923a912008-03-12 21:04:07 +0000571 RVal V = StateMgr.GetRVal(St, *I);
Ted Kremenek06747692008-02-26 23:04:29 +0000572
573 if (isa<LVal>(V))
Ted Kremenekf923a912008-03-12 21:04:07 +0000574 St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
Ted Kremeneka5488462008-04-22 21:39:21 +0000575 else if (isa<nonlval::LValAsInteger>(V))
576 St = StateMgr.SetRVal(St, cast<nonlval::LValAsInteger>(V).getLVal(),
577 UnknownVal());
578
Ted Kremenek06747692008-02-26 23:04:29 +0000579 }
Ted Kremenekf923a912008-03-12 21:04:07 +0000580
581 // Make up a symbol for the return value of this function.
582
583 if (CE->getType() != Eng.getContext().VoidTy) {
584 unsigned Count = Builder.getCurrentBlockCount();
Ted Kremenek361fa8e2008-03-12 21:45:47 +0000585 SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(CE, Count);
Ted Kremenekf923a912008-03-12 21:04:07 +0000586
587 RVal X = CE->getType()->isPointerType()
588 ? cast<RVal>(lval::SymbolVal(Sym))
589 : cast<RVal>(nonlval::SymbolVal(Sym));
590
591 St = StateMgr.SetRVal(St, CE, X, Eng.getCFG().isBlkExpr(CE), false);
592 }
Ted Kremenek330dddd2008-03-05 00:33:14 +0000593
Ted Kremenek0e561a32008-03-21 21:30:14 +0000594 Builder.MakeNode(Dst, CE, Pred, St);
Ted Kremenek06747692008-02-26 23:04:29 +0000595}
Ted Kremeneke695e1c2008-04-15 23:06:53 +0000596
597//===----------------------------------------------------------------------===//
598// Transfer function for Objective-C message expressions.
599//===----------------------------------------------------------------------===//
600
601void GRSimpleVals::EvalObjCMessageExpr(ExplodedNodeSet<ValueState>& Dst,
602 GRExprEngine& Eng,
603 GRStmtNodeBuilder<ValueState>& Builder,
604 ObjCMessageExpr* ME,
605 ExplodedNode<ValueState>* Pred) {
606
607
608 // The basic transfer function logic for message expressions does nothing.
609 // We just invalidate all arguments passed in by references.
610
611 ValueStateManager& StateMgr = Eng.getStateManager();
612 ValueState* St = Builder.GetState(Pred);
613
614 for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end();
615 I != E; ++I) {
616
617 RVal V = StateMgr.GetRVal(St, *I);
618
619 if (isa<LVal>(V))
620 St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
621 }
622
623 Builder.MakeNode(Dst, ME, Pred, St);
624}