blob: cc31ddddef84bd7ad43e60fa282c2367793544d9 [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 Kremenekc0c3f5d2008-04-30 20:17:27 +000023#include "clang/Analysis/PathSensitive/GRExprEngine.h"
Ted Kremenek61f3e052008-04-03 04:42:52 +000024#include "llvm/Support/Compiler.h"
Ted Kremenek5c061212008-02-27 17:56:16 +000025#include <sstream>
Ted Kremenekd59cccc2008-02-14 18:28:23 +000026
27using namespace clang;
28
Ted Kremenekdd598112008-04-02 07:05:46 +000029//===----------------------------------------------------------------------===//
Ted Kremenekdd598112008-04-02 07:05:46 +000030// Utility functions.
31//===----------------------------------------------------------------------===//
Ted Kremenek50a6d0c2008-04-09 21:41:14 +000032
Chris Lattner3ae30f82008-04-06 04:22:39 +000033template <typename ITERATOR> inline
Ted Kremenek61f3e052008-04-03 04:42:52 +000034ExplodedNode<ValueState>* GetNode(ITERATOR I) {
Ted Kremenek503d6132008-04-02 05:15:22 +000035 return *I;
36}
37
Chris Lattner3ae30f82008-04-06 04:22:39 +000038template <> inline
Ted Kremenek61f3e052008-04-03 04:42:52 +000039ExplodedNode<ValueState>* GetNode(GRExprEngine::undef_arg_iterator I) {
Ted Kremenek503d6132008-04-02 05:15:22 +000040 return I->first;
41}
Ted Kremenekdd598112008-04-02 07:05:46 +000042
Ted Kremenek50a6d0c2008-04-09 21:41:14 +000043template <typename ITER>
Ted Kremenek95cc1ba2008-04-18 20:54:29 +000044void GenericEmitWarnings(BugReporter& BR, BugType& D, ITER I, ITER E) {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +000045
46 for (; I != E; ++I) {
Ted Kremenekd2f642b2008-04-14 17:39:48 +000047 BugReport R(D, GetNode(I));
Ted Kremenek75840e12008-04-18 01:56:37 +000048 BR.EmitWarning(R);
Ted Kremenek50a6d0c2008-04-09 21:41:14 +000049 }
50}
51
52//===----------------------------------------------------------------------===//
53// Bug Descriptions.
54//===----------------------------------------------------------------------===//
55
56namespace {
57
Ted Kremenek95cc1ba2008-04-18 20:54:29 +000058class VISIBILITY_HIDDEN NullDeref : public BugTypeCacheLocation {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +000059public:
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) {
Ted Kremenekc0959972008-07-02 21:24:01 +000069 GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
Ted Kremenek50a6d0c2008-04-09 21:41:14 +000070 GenericEmitWarnings(BR, *this, Eng.null_derefs_begin(),
71 Eng.null_derefs_end());
72 }
73};
74
Ted Kremenek95cc1ba2008-04-18 20:54:29 +000075class VISIBILITY_HIDDEN UndefDeref : public BugTypeCacheLocation {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +000076public:
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) {
Ted Kremenekc0959972008-07-02 21:24:01 +000086 GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
Ted Kremenek50a6d0c2008-04-09 21:41:14 +000087 GenericEmitWarnings(BR, *this, Eng.undef_derefs_begin(),
88 Eng.undef_derefs_end());
89 }
90};
91
Ted Kremenek95cc1ba2008-04-18 20:54:29 +000092class VISIBILITY_HIDDEN UndefBranch : public BugTypeCacheLocation {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +000093public:
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
Ted Kremenek5c454ab2008-05-05 15:56:53 +0000102 virtual void EmitWarnings(BugReporter& BR);
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000103};
104
Ted Kremenek95cc1ba2008-04-18 20:54:29 +0000105class VISIBILITY_HIDDEN DivZero : public BugTypeCacheLocation {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000106public:
107 virtual const char* getName() const {
108 return "divide-by-zero";
109 }
110
111 virtual const char* getDescription() const {
112 return "Division by zero/undefined value.";
113 }
114
115 virtual void EmitWarnings(BugReporter& BR) {
Ted Kremenekc0959972008-07-02 21:24:01 +0000116 GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000117 GenericEmitWarnings(BR, *this, Eng.explicit_bad_divides_begin(),
118 Eng.explicit_bad_divides_end());
119 }
120};
121
Ted Kremenek95cc1ba2008-04-18 20:54:29 +0000122class VISIBILITY_HIDDEN UndefResult : public BugTypeCacheLocation {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000123public:
124 virtual const char* getName() const {
125 return "undefined result";
126 }
127
128 virtual const char* getDescription() const {
129 return "Result of operation is undefined.";
130 }
131
132 virtual void EmitWarnings(BugReporter& BR) {
Ted Kremenekc0959972008-07-02 21:24:01 +0000133 GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000134 GenericEmitWarnings(BR, *this, Eng.undef_results_begin(),
Ted Kremenek4d35dac2008-04-10 16:05:13 +0000135 Eng.undef_results_end());
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000136 }
137};
138
Ted Kremenek95cc1ba2008-04-18 20:54:29 +0000139class VISIBILITY_HIDDEN BadCall : public BugTypeCacheLocation {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000140public:
141 virtual const char* getName() const {
142 return "invalid function call";
143 }
144
145 virtual const char* getDescription() const {
146 return "Called function is a NULL or undefined function pointer value.";
147 }
148
149 virtual void EmitWarnings(BugReporter& BR) {
Ted Kremenekc0959972008-07-02 21:24:01 +0000150 GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000151 GenericEmitWarnings(BR, *this, Eng.bad_calls_begin(),
Ted Kremenek4d35dac2008-04-10 16:05:13 +0000152 Eng.bad_calls_end());
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000153 }
154};
155
156
Ted Kremenek95cc1ba2008-04-18 20:54:29 +0000157class VISIBILITY_HIDDEN BadArg : public BugTypeCacheLocation {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000158public:
159
160 virtual ~BadArg() {}
161
162 virtual const char* getName() const {
163 return "bad argument";
164 }
165
166 virtual const char* getDescription() const {
167 return "Pass-by-value argument in function is undefined.";
168 }
169
170 virtual void EmitWarnings(BugReporter& BR) {
Ted Kremenekc0959972008-07-02 21:24:01 +0000171 GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000172
173 for (GRExprEngine::UndefArgsTy::iterator I = Eng.undef_arg_begin(),
174 E = Eng.undef_arg_end(); I!=E; ++I) {
175
176 // Generate a report for this bug.
Ted Kremenekd2f642b2008-04-14 17:39:48 +0000177 RangedBugReport report(*this, I->first);
178 report.addRange(I->second->getSourceRange());
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000179
180 // Emit the warning.
Ted Kremenek75840e12008-04-18 01:56:37 +0000181 BR.EmitWarning(report);
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000182 }
183
184 }
185};
186
187class VISIBILITY_HIDDEN BadMsgExprArg : public BadArg {
188public:
189 virtual const char* getName() const {
190 return "bad argument";
191 }
192
193 virtual const char* getDescription() const {
194 return "Pass-by-value argument in message expression is undefined.";
195 }
196
197 virtual void EmitWarnings(BugReporter& BR) {
Ted Kremenekc0959972008-07-02 21:24:01 +0000198 GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000199
200 for (GRExprEngine::UndefArgsTy::iterator I=Eng.msg_expr_undef_arg_begin(),
Ted Kremenek4d35dac2008-04-10 16:05:13 +0000201 E = Eng.msg_expr_undef_arg_end(); I!=E; ++I) {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000202
203 // Generate a report for this bug.
Ted Kremenekd2f642b2008-04-14 17:39:48 +0000204 RangedBugReport report(*this, I->first);
205 report.addRange(I->second->getSourceRange());
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000206
207 // Emit the warning.
Ted Kremenek75840e12008-04-18 01:56:37 +0000208 BR.EmitWarning(report);
Ted Kremenekd2f642b2008-04-14 17:39:48 +0000209 }
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000210 }
211};
212
Ted Kremenek95cc1ba2008-04-18 20:54:29 +0000213class VISIBILITY_HIDDEN BadReceiver : public BugTypeCacheLocation {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000214public:
215 virtual const char* getName() const {
216 return "bad receiver";
217 }
218
219 virtual const char* getDescription() const {
220 return "Receiver in message expression is an uninitialized value.";
221 }
222
223 virtual void EmitWarnings(BugReporter& BR) {
Ted Kremenekc0959972008-07-02 21:24:01 +0000224 GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000225
226 for (GRExprEngine::UndefReceiversTy::iterator I=Eng.undef_receivers_begin(),
Argyrios Kyrtzidisafe10912008-04-15 16:30:10 +0000227 End = Eng.undef_receivers_end(); I!=End; ++I) {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000228
229 // Generate a report for this bug.
Ted Kremenekd2f642b2008-04-14 17:39:48 +0000230 RangedBugReport report(*this, *I);
231
232 ExplodedNode<ValueState>* N = *I;
233 Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
234 Expr* E = cast<ObjCMessageExpr>(S)->getReceiver();
235 assert (E && "Receiver cannot be NULL");
236 report.addRange(E->getSourceRange());
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000237
238 // Emit the warning.
Ted Kremenek75840e12008-04-18 01:56:37 +0000239 BR.EmitWarning(report);
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000240 }
241 }
242};
243
Ted Kremenek95cc1ba2008-04-18 20:54:29 +0000244class VISIBILITY_HIDDEN RetStack : public BugTypeCacheLocation {
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000245public:
246 virtual const char* getName() const {
247 return "return of stack address";
248 }
249
250 virtual const char* getDescription() const {
251 return "Address of stack-allocated variable returned.";
252 }
253
254 virtual void EmitWarnings(BugReporter& BR) {
Ted Kremenekc0959972008-07-02 21:24:01 +0000255 GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000256 GenericEmitWarnings(BR, *this, Eng.ret_stackaddr_begin(),
Ted Kremenek4d35dac2008-04-10 16:05:13 +0000257 Eng.ret_stackaddr_end());
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000258 }
259};
260
261} // end anonymous namespace
262
Ted Kremenek5c454ab2008-05-05 15:56:53 +0000263
264namespace {
265
266struct VISIBILITY_HIDDEN FindUndefExpr {
267 ValueStateManager& VM;
Ted Kremenek4323a572008-07-10 22:03:41 +0000268 const ValueState* St;
Ted Kremenek5c454ab2008-05-05 15:56:53 +0000269
Ted Kremenek4323a572008-07-10 22:03:41 +0000270 FindUndefExpr(ValueStateManager& V, const ValueState* S) : VM(V), St(S) {}
Ted Kremenek5c454ab2008-05-05 15:56:53 +0000271
272 Expr* FindExpr(Expr* Ex) {
273
274 if (!MatchesCriteria(Ex))
275 return 0;
276
277 for (Stmt::child_iterator I=Ex->child_begin(), E=Ex->child_end(); I!=E; ++I)
278 if (Expr* ExI = dyn_cast_or_null<Expr>(*I)) {
279 Expr* E2 = FindExpr(ExI);
280 if (E2) return E2;
281 }
282
283 return Ex;
284 }
285
286 bool MatchesCriteria(Expr* Ex) { return VM.GetRVal(St, Ex).isUndef(); }
287};
288
289} // end anonymous namespace
290
291
292void UndefBranch::EmitWarnings(BugReporter& BR) {
293
Ted Kremenekc0959972008-07-02 21:24:01 +0000294 GRExprEngine& Eng = cast<GRBugReporter>(BR).getEngine();
Ted Kremenek5c454ab2008-05-05 15:56:53 +0000295
296 for (GRExprEngine::undef_branch_iterator I=Eng.undef_branches_begin(),
297 E=Eng.undef_branches_end(); I!=E; ++I) {
298
299 // What's going on here: we want to highlight the subexpression of the
300 // condition that is the most likely source of the "uninitialized
301 // branch condition." We do a recursive walk of the condition's
302 // subexpressions and roughly look for the most nested subexpression
303 // that binds to Undefined. We then highlight that expression's range.
304
305 BlockEdge B = cast<BlockEdge>((*I)->getLocation());
306 Expr* Ex = cast<Expr>(B.getSrc()->getTerminatorCondition());
307 assert (Ex && "Block must have a terminator.");
308
309 // Get the predecessor node and check if is a PostStmt with the Stmt
310 // being the terminator condition. We want to inspect the state
311 // of that node instead because it will contain main information about
312 // the subexpressions.
313
314 assert (!(*I)->pred_empty());
315
316 // Note: any predecessor will do. They should have identical state,
317 // since all the BlockEdge did was act as an error sink since the value
318 // had to already be undefined.
319 ExplodedNode<ValueState> *N = *(*I)->pred_begin();
320 ProgramPoint P = N->getLocation();
321
Ted Kremenek4323a572008-07-10 22:03:41 +0000322 const ValueState* St = (*I)->getState();
Ted Kremenek5c454ab2008-05-05 15:56:53 +0000323
324 if (PostStmt* PS = dyn_cast<PostStmt>(&P))
325 if (PS->getStmt() == Ex)
326 St = N->getState();
327
328 FindUndefExpr FindIt(Eng.getStateManager(), St);
329 Ex = FindIt.FindExpr(Ex);
330
331 RangedBugReport R(*this, *I);
332 R.addRange(Ex->getSourceRange());
333
334 BR.EmitWarning(R);
335 }
336}
337
338
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000339void GRSimpleVals::RegisterChecks(GRExprEngine& Eng) {
Ted Kremenekd2f642b2008-04-14 17:39:48 +0000340
341 // Path-sensitive checks.
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000342 Eng.Register(new NullDeref());
343 Eng.Register(new UndefDeref());
344 Eng.Register(new UndefBranch());
345 Eng.Register(new DivZero());
346 Eng.Register(new UndefResult());
347 Eng.Register(new BadCall());
348 Eng.Register(new RetStack());
349 Eng.Register(new BadArg());
350 Eng.Register(new BadMsgExprArg());
351 Eng.Register(new BadReceiver());
352
353 // Add extra checkers.
Ted Kremenek04bc8762008-06-26 23:59:48 +0000354 ASTContext& Ctx = Eng.getContext();
355 ValueStateManager* VMgr = &Eng.getStateManager();
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000356
Ted Kremenekbdb435d2008-07-11 18:37:32 +0000357 GRSimpleAPICheck* Check = CreateBasicObjCFoundationChecks(Ctx, VMgr);
358 Eng.AddCheck(Check, Stmt::ObjCMessageExprClass);
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000359
Ted Kremenekbdb435d2008-07-11 18:37:32 +0000360 Check = CreateAuditCFNumberCreate(Ctx, VMgr);
361 Eng.AddCheck(Check, Stmt::CallExprClass);
Ted Kremenek04bc8762008-06-26 23:59:48 +0000362
Ted Kremenek50a6d0c2008-04-09 21:41:14 +0000363}
364
Ted Kremenekdd598112008-04-02 07:05:46 +0000365//===----------------------------------------------------------------------===//
Ted Kremenekd71ed262008-04-10 22:16:52 +0000366// Transfer Function creation for External clients.
Ted Kremenek503d6132008-04-02 05:15:22 +0000367//===----------------------------------------------------------------------===//
Ted Kremenek61f3e052008-04-03 04:42:52 +0000368
Ted Kremenekd71ed262008-04-10 22:16:52 +0000369GRTransferFuncs* clang::MakeGRSimpleValsTF() { return new GRSimpleVals(); }
Ted Kremeneke01c9872008-02-14 22:36:46 +0000370
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000371//===----------------------------------------------------------------------===//
372// Transfer function for Casts.
373//===----------------------------------------------------------------------===//
374
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000375RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, NonLVal X, QualType T) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000376
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000377 if (!isa<nonlval::ConcreteInt>(X))
378 return UnknownVal();
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000379
Ted Kremenekcd512dc2008-07-16 00:23:49 +0000380 bool isLValType = LVal::IsLValType(T);
381
Ted Kremenekf496ee12008-07-15 23:17:54 +0000382 // Only handle casts from integers to integers.
Ted Kremenekcd512dc2008-07-16 00:23:49 +0000383 if (!isLValType && !T->isIntegerType())
Ted Kremenekf496ee12008-07-15 23:17:54 +0000384 return UnknownVal();
385
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000386 BasicValueFactory& BasicVals = Eng.getBasicVals();
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000387
388 llvm::APSInt V = cast<nonlval::ConcreteInt>(X).getValue();
Ted Kremenek0e470a52008-05-09 23:45:33 +0000389 V.setIsUnsigned(T->isUnsignedIntegerType() || LVal::IsLValType(T));
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000390 V.extOrTrunc(Eng.getContext().getTypeSize(T));
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000391
Ted Kremenekcd512dc2008-07-16 00:23:49 +0000392 if (isLValType)
Ted Kremenek240f1f02008-03-07 20:13:31 +0000393 return lval::ConcreteInt(BasicVals.getValue(V));
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000394 else
Ted Kremenek240f1f02008-03-07 20:13:31 +0000395 return nonlval::ConcreteInt(BasicVals.getValue(V));
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000396}
397
398// Casts.
399
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000400RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, LVal X, QualType T) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000401
Ted Kremeneke8c2bde2008-04-30 21:10:19 +0000402 // Casts from pointers -> pointers, just return the lval.
403 //
404 // Casts from pointers -> references, just return the lval. These
405 // can be introduced by the frontend for corner cases, e.g
406 // casting from va_list* to __builtin_va_list&.
407 //
Ted Kremenek0e470a52008-05-09 23:45:33 +0000408 if (LVal::IsLValType(T) || T->isReferenceType())
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000409 return X;
410
Ted Kremenek9ef1ec92008-02-21 18:43:30 +0000411 assert (T->isIntegerType());
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000412
413 if (!isa<lval::ConcreteInt>(X))
414 return UnknownVal();
415
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000416 BasicValueFactory& BasicVals = Eng.getBasicVals();
417
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000418 llvm::APSInt V = cast<lval::ConcreteInt>(X).getValue();
Ted Kremenek0e470a52008-05-09 23:45:33 +0000419 V.setIsUnsigned(T->isUnsignedIntegerType() || LVal::IsLValType(T));
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000420 V.extOrTrunc(Eng.getContext().getTypeSize(T));
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000421
Ted Kremenek240f1f02008-03-07 20:13:31 +0000422 return nonlval::ConcreteInt(BasicVals.getValue(V));
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000423}
424
425// Unary operators.
426
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000427RVal GRSimpleVals::EvalMinus(GRExprEngine& Eng, UnaryOperator* U, NonLVal X){
Ted Kremenek692416c2008-02-18 22:57:02 +0000428
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000429 switch (X.getSubKind()) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000430
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000431 case nonlval::ConcreteIntKind:
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000432 return cast<nonlval::ConcreteInt>(X).EvalMinus(Eng.getBasicVals(), U);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000433
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000434 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000435 return UnknownVal();
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000436 }
437}
438
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000439RVal GRSimpleVals::EvalComplement(GRExprEngine& Eng, NonLVal X) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000440
Ted Kremenek90e42032008-02-20 04:12:31 +0000441 switch (X.getSubKind()) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000442
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000443 case nonlval::ConcreteIntKind:
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000444 return cast<nonlval::ConcreteInt>(X).EvalComplement(Eng.getBasicVals());
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000445
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000446 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000447 return UnknownVal();
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000448 }
449}
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000450
451// Binary operators.
452
Ted Kremenekad8329e2008-07-18 15:27:58 +0000453RVal GRSimpleVals::DetermEvalBinOpNN(ValueStateManager& StateMgr,
454 BinaryOperator::Opcode Op,
455 NonLVal L, NonLVal R) {
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000456
Ted Kremenek6297a8e2008-07-18 05:53:58 +0000457 BasicValueFactory& BasicVals = StateMgr.getBasicVals();
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000458
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000459 while (1) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000460
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000461 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000462 default:
Ted Kremenek9258a642008-02-21 19:10:12 +0000463 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000464
465 case nonlval::ConcreteIntKind:
466
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000467 if (isa<nonlval::ConcreteInt>(R)) {
468 const nonlval::ConcreteInt& L_CI = cast<nonlval::ConcreteInt>(L);
469 const nonlval::ConcreteInt& R_CI = cast<nonlval::ConcreteInt>(R);
Ted Kremenek240f1f02008-03-07 20:13:31 +0000470 return L_CI.EvalBinOp(BasicVals, Op, R_CI);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000471 }
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000472 else {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000473 NonLVal tmp = R;
474 R = L;
475 L = tmp;
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000476 continue;
477 }
478
479 case nonlval::SymbolValKind: {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000480
481 if (isa<nonlval::ConcreteInt>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000482 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000483 BasicVals.getConstraint(cast<nonlval::SymbolVal>(L).getSymbol(), Op,
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000484 cast<nonlval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000485
486 return nonlval::SymIntConstraintVal(C);
487 }
488 else
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000489 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000490 }
491 }
492 }
493}
494
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000495
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000496// Binary Operators (except assignments and comma).
497
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000498RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000499 LVal L, LVal R) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000500
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000501 switch (Op) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000502
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000503 default:
504 return UnknownVal();
505
506 case BinaryOperator::EQ:
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000507 return EvalEQ(Eng, L, R);
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000508
509 case BinaryOperator::NE:
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000510 return EvalNE(Eng, L, R);
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000511 }
512}
513
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000514// Pointer arithmetic.
515
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000516RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000517 LVal L, NonLVal R) {
518 return UnknownVal();
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000519}
520
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000521// Equality operators for LVals.
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000522
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000523RVal GRSimpleVals::EvalEQ(GRExprEngine& Eng, LVal L, LVal R) {
524
525 BasicValueFactory& BasicVals = Eng.getBasicVals();
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000526
527 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000528
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000529 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000530 assert(false && "EQ not implemented for this LVal.");
531 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000532
533 case lval::ConcreteIntKind:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000534
535 if (isa<lval::ConcreteInt>(R)) {
536 bool b = cast<lval::ConcreteInt>(L).getValue() ==
537 cast<lval::ConcreteInt>(R).getValue();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000538
Ted Kremenek240f1f02008-03-07 20:13:31 +0000539 return NonLVal::MakeIntTruthVal(BasicVals, b);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000540 }
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000541 else if (isa<lval::SymbolVal>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000542
543 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000544 BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000545 BinaryOperator::EQ,
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000546 cast<lval::ConcreteInt>(L).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000547
548 return nonlval::SymIntConstraintVal(C);
549 }
550
551 break;
552
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000553 case lval::SymbolValKind: {
554
555 if (isa<lval::ConcreteInt>(R)) {
556 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000557 BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000558 BinaryOperator::EQ,
559 cast<lval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000560
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000561 return nonlval::SymIntConstraintVal(C);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000562 }
563
Ted Kremenekf700df22008-02-22 18:41:59 +0000564 // FIXME: Implement == for lval Symbols. This is mainly useful
565 // in iterator loops when traversing a buffer, e.g. while(z != zTerm).
566 // Since this is not useful for many checkers we'll punt on this for
567 // now.
568
569 return UnknownVal();
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000570 }
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000571
Ted Kremenekc3b7f0e2008-04-30 16:07:22 +0000572 // FIXME: Different offsets can map to the same memory cell.
573 case lval::ArrayOffsetKind:
574 case lval::FieldOffsetKind:
575 // Fall-through.
576
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000577 case lval::DeclValKind:
Ted Kremenekdc3936b2008-02-22 00:54:56 +0000578 case lval::FuncValKind:
579 case lval::GotoLabelKind:
Ted Kremenek666de3b2008-05-12 17:41:30 +0000580 case lval::StringLiteralValKind:
Ted Kremenek240f1f02008-03-07 20:13:31 +0000581 return NonLVal::MakeIntTruthVal(BasicVals, L == R);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000582 }
583
Ted Kremenek240f1f02008-03-07 20:13:31 +0000584 return NonLVal::MakeIntTruthVal(BasicVals, false);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000585}
586
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000587RVal GRSimpleVals::EvalNE(GRExprEngine& Eng, LVal L, LVal R) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000588
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000589 BasicValueFactory& BasicVals = Eng.getBasicVals();
590
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000591 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000592
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000593 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000594 assert(false && "NE not implemented for this LVal.");
595 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000596
597 case lval::ConcreteIntKind:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000598
599 if (isa<lval::ConcreteInt>(R)) {
600 bool b = cast<lval::ConcreteInt>(L).getValue() !=
601 cast<lval::ConcreteInt>(R).getValue();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000602
Ted Kremenek240f1f02008-03-07 20:13:31 +0000603 return NonLVal::MakeIntTruthVal(BasicVals, b);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000604 }
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000605 else if (isa<lval::SymbolVal>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000606 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000607 BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000608 BinaryOperator::NE,
609 cast<lval::ConcreteInt>(L).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000610
611 return nonlval::SymIntConstraintVal(C);
612 }
613
614 break;
615
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000616 case lval::SymbolValKind: {
617 if (isa<lval::ConcreteInt>(R)) {
618 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000619 BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000620 BinaryOperator::NE,
621 cast<lval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000622
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000623 return nonlval::SymIntConstraintVal(C);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000624 }
625
Ted Kremenekf700df22008-02-22 18:41:59 +0000626 // FIXME: Implement != for lval Symbols. This is mainly useful
627 // in iterator loops when traversing a buffer, e.g. while(z != zTerm).
628 // Since this is not useful for many checkers we'll punt on this for
629 // now.
630
631 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000632
633 break;
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000634 }
635
Ted Kremenekc3b7f0e2008-04-30 16:07:22 +0000636 // FIXME: Different offsets can map to the same memory cell.
637 case lval::ArrayOffsetKind:
638 case lval::FieldOffsetKind:
639 // Fall-through.
640
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000641 case lval::DeclValKind:
Ted Kremenekdc3936b2008-02-22 00:54:56 +0000642 case lval::FuncValKind:
643 case lval::GotoLabelKind:
Ted Kremenek666de3b2008-05-12 17:41:30 +0000644 case lval::StringLiteralValKind:
Ted Kremenek240f1f02008-03-07 20:13:31 +0000645 return NonLVal::MakeIntTruthVal(BasicVals, L != R);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000646 }
647
Ted Kremenek240f1f02008-03-07 20:13:31 +0000648 return NonLVal::MakeIntTruthVal(BasicVals, true);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000649}
Ted Kremenek06747692008-02-26 23:04:29 +0000650
651//===----------------------------------------------------------------------===//
Ted Kremeneke695e1c2008-04-15 23:06:53 +0000652// Transfer function for function calls.
Ted Kremenek06747692008-02-26 23:04:29 +0000653//===----------------------------------------------------------------------===//
654
Ted Kremenek330dddd2008-03-05 00:33:14 +0000655void GRSimpleVals::EvalCall(ExplodedNodeSet<ValueState>& Dst,
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000656 GRExprEngine& Eng,
Ted Kremenek330dddd2008-03-05 00:33:14 +0000657 GRStmtNodeBuilder<ValueState>& Builder,
Ted Kremenek186350f2008-04-23 20:12:28 +0000658 CallExpr* CE, RVal L,
Ted Kremenek330dddd2008-03-05 00:33:14 +0000659 ExplodedNode<ValueState>* Pred) {
660
Ted Kremenekf923a912008-03-12 21:04:07 +0000661 ValueStateManager& StateMgr = Eng.getStateManager();
Ted Kremenek4323a572008-07-10 22:03:41 +0000662 const ValueState* St = Builder.GetState(Pred);
Ted Kremenek06747692008-02-26 23:04:29 +0000663
664 // Invalidate all arguments passed in by reference (LVals).
665
666 for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
667 I != E; ++I) {
668
Ted Kremenekf923a912008-03-12 21:04:07 +0000669 RVal V = StateMgr.GetRVal(St, *I);
Ted Kremenek06747692008-02-26 23:04:29 +0000670
671 if (isa<LVal>(V))
Ted Kremenekf923a912008-03-12 21:04:07 +0000672 St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
Ted Kremeneka5488462008-04-22 21:39:21 +0000673 else if (isa<nonlval::LValAsInteger>(V))
674 St = StateMgr.SetRVal(St, cast<nonlval::LValAsInteger>(V).getLVal(),
675 UnknownVal());
676
Ted Kremenek06747692008-02-26 23:04:29 +0000677 }
Ted Kremenekf923a912008-03-12 21:04:07 +0000678
679 // Make up a symbol for the return value of this function.
680
681 if (CE->getType() != Eng.getContext().VoidTy) {
682 unsigned Count = Builder.getCurrentBlockCount();
Ted Kremenek361fa8e2008-03-12 21:45:47 +0000683 SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(CE, Count);
Ted Kremenekf923a912008-03-12 21:04:07 +0000684
Ted Kremenek0e470a52008-05-09 23:45:33 +0000685 RVal X = LVal::IsLValType(CE->getType())
Ted Kremenekf923a912008-03-12 21:04:07 +0000686 ? cast<RVal>(lval::SymbolVal(Sym))
687 : cast<RVal>(nonlval::SymbolVal(Sym));
688
689 St = StateMgr.SetRVal(St, CE, X, Eng.getCFG().isBlkExpr(CE), false);
690 }
Ted Kremenek330dddd2008-03-05 00:33:14 +0000691
Ted Kremenek0e561a32008-03-21 21:30:14 +0000692 Builder.MakeNode(Dst, CE, Pred, St);
Ted Kremenek06747692008-02-26 23:04:29 +0000693}
Ted Kremeneke695e1c2008-04-15 23:06:53 +0000694
695//===----------------------------------------------------------------------===//
696// Transfer function for Objective-C message expressions.
697//===----------------------------------------------------------------------===//
698
699void GRSimpleVals::EvalObjCMessageExpr(ExplodedNodeSet<ValueState>& Dst,
700 GRExprEngine& Eng,
701 GRStmtNodeBuilder<ValueState>& Builder,
702 ObjCMessageExpr* ME,
703 ExplodedNode<ValueState>* Pred) {
704
705
706 // The basic transfer function logic for message expressions does nothing.
707 // We just invalidate all arguments passed in by references.
708
709 ValueStateManager& StateMgr = Eng.getStateManager();
Ted Kremenek4323a572008-07-10 22:03:41 +0000710 const ValueState* St = Builder.GetState(Pred);
Ted Kremeneke695e1c2008-04-15 23:06:53 +0000711
712 for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end();
713 I != E; ++I) {
714
715 RVal V = StateMgr.GetRVal(St, *I);
716
717 if (isa<LVal>(V))
718 St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
719 }
720
721 Builder.MakeNode(Dst, ME, Pred, St);
722}