blob: c4eddb9993605d5a23ccbfa553b8c0b85f182dbe [file] [log] [blame]
Ted Kremenek50df4f42008-02-14 22:13:12 +00001//=-- GRExprEngine.cpp - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=
Ted Kremenekc48b8e42008-01-31 02:35:41 +00002//
Ted Kremenek2e160602008-01-31 06:49:09 +00003// The LLVM Compiler Infrastructure
Ted Kremenek68d70a82008-01-15 23:55:06 +00004//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Ted Kremenek50df4f42008-02-14 22:13:12 +000010// This file defines a meta-engine for path-sensitive dataflow analysis that
11// is built on GREngine, but provides the boilerplate to execute transfer
12// functions and build the ExplodedGraph at the expression level.
Ted Kremenek68d70a82008-01-15 23:55:06 +000013//
14//===----------------------------------------------------------------------===//
15
Ted Kremenek50df4f42008-02-14 22:13:12 +000016#include "clang/Analysis/PathSensitive/GRExprEngine.h"
Ted Kremenek0e80dea2008-04-09 21:41:14 +000017#include "clang/Analysis/PathSensitive/BugReporter.h"
Ted Kremenek8b41e8c2008-03-07 20:57:30 +000018#include "clang/Basic/SourceManager.h"
Ted Kremenek3862eb12008-02-14 22:36:46 +000019#include "llvm/Support/Streams.h"
Ted Kremenekd4467432008-02-14 22:16:04 +000020
Ted Kremenek9f6b1612008-02-27 06:07:00 +000021#ifndef NDEBUG
22#include "llvm/Support/GraphWriter.h"
23#include <sstream>
24#endif
25
Ted Kremenekd4467432008-02-14 22:16:04 +000026using namespace clang;
27using llvm::dyn_cast;
28using llvm::cast;
29using llvm::APSInt;
Ted Kremenekf031b872008-01-23 19:59:44 +000030
Ted Kremenekca5f6202008-04-15 23:06:53 +000031//===----------------------------------------------------------------------===//
32// Engine construction and deletion.
33//===----------------------------------------------------------------------===//
34
Ted Kremenek5f20a632008-05-01 18:33:28 +000035static inline Selector GetNullarySelector(const char* name, ASTContext& Ctx) {
36 IdentifierInfo* II = &Ctx.Idents.get(name);
37 return Ctx.Selectors.getSelector(0, &II);
38}
39
Ted Kremenekf973eb02008-03-09 18:05:48 +000040
Ted Kremenek1607f512008-07-02 20:13:38 +000041GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx,
42 LiveVariables& L)
Ted Kremenek0e80dea2008-04-09 21:41:14 +000043 : CoreEngine(cfg, CD, Ctx, *this),
44 G(CoreEngine.getGraph()),
Ted Kremenek1607f512008-07-02 20:13:38 +000045 Liveness(L),
Ted Kremenek0e80dea2008-04-09 21:41:14 +000046 Builder(NULL),
47 StateMgr(G.getContext(), G.getAllocator()),
48 BasicVals(StateMgr.getBasicValueFactory()),
49 TF(NULL), // FIXME
50 SymMgr(StateMgr.getSymbolManager()),
Ted Kremenek5f20a632008-05-01 18:33:28 +000051 CurrentStmt(NULL),
52 NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
Ted Kremenek1607f512008-07-02 20:13:38 +000053 RaiseSel(GetNullarySelector("raise", G.getContext())) {}
Ted Kremenek0e80dea2008-04-09 21:41:14 +000054
Ted Kremenek72f52c02008-06-20 21:45:25 +000055GRExprEngine::~GRExprEngine() {
Ted Kremenek0e80dea2008-04-09 21:41:14 +000056 for (BugTypeSet::iterator I = BugTypes.begin(), E = BugTypes.end(); I!=E; ++I)
57 delete *I;
58
59 for (SimpleChecksTy::iterator I = CallChecks.begin(), E = CallChecks.end();
60 I != E; ++I)
61 delete *I;
62
63 for (SimpleChecksTy::iterator I=MsgExprChecks.begin(), E=MsgExprChecks.end();
64 I != E; ++I)
65 delete *I;
Ted Kremenek5f20a632008-05-01 18:33:28 +000066
67 delete [] NSExceptionInstanceRaiseSelectors;
Ted Kremenek0e80dea2008-04-09 21:41:14 +000068}
69
Ted Kremenekca5f6202008-04-15 23:06:53 +000070//===----------------------------------------------------------------------===//
71// Utility methods.
72//===----------------------------------------------------------------------===//
73
74// SaveAndRestore - A utility class that uses RIIA to save and restore
75// the value of a variable.
76template<typename T>
77struct VISIBILITY_HIDDEN SaveAndRestore {
78 SaveAndRestore(T& x) : X(x), old_value(x) {}
79 ~SaveAndRestore() { X = old_value; }
80 T get() { return old_value; }
81
82 T& X;
83 T old_value;
84};
85
Ted Kremenek0a6a80b2008-04-23 20:12:28 +000086// SaveOr - Similar to SaveAndRestore. Operates only on bools; the old
87// value of a variable is saved, and during the dstor the old value is
88// or'ed with the new value.
89struct VISIBILITY_HIDDEN SaveOr {
90 SaveOr(bool& x) : X(x), old_value(x) { x = false; }
91 ~SaveOr() { X |= old_value; }
92
93 bool& X;
94 bool old_value;
95};
96
97
Ted Kremenekba1c7ed2008-07-02 21:24:01 +000098void GRExprEngine::EmitWarnings(BugReporterData& BRData) {
Ted Kremenek0e80dea2008-04-09 21:41:14 +000099 for (bug_type_iterator I = bug_types_begin(), E = bug_types_end(); I!=E; ++I){
Ted Kremenekba1c7ed2008-07-02 21:24:01 +0000100 GRBugReporter BR(BRData, *this);
Ted Kremenek0e80dea2008-04-09 21:41:14 +0000101 (*I)->EmitWarnings(BR);
102 }
103
104 for (SimpleChecksTy::iterator I = CallChecks.begin(), E = CallChecks.end();
105 I != E; ++I) {
Ted Kremenekba1c7ed2008-07-02 21:24:01 +0000106 GRBugReporter BR(BRData, *this);
Ted Kremenek0e80dea2008-04-09 21:41:14 +0000107 (*I)->EmitWarnings(BR);
108 }
109
110 for (SimpleChecksTy::iterator I=MsgExprChecks.begin(), E=MsgExprChecks.end();
111 I != E; ++I) {
Ted Kremenekba1c7ed2008-07-02 21:24:01 +0000112 GRBugReporter BR(BRData, *this);
Ted Kremenek0e80dea2008-04-09 21:41:14 +0000113 (*I)->EmitWarnings(BR);
114 }
115}
116
117void GRExprEngine::setTransferFunctions(GRTransferFuncs* tf) {
118 TF = tf;
119 TF->RegisterChecks(*this);
120}
121
122void GRExprEngine::AddCallCheck(GRSimpleAPICheck* A) {
123 CallChecks.push_back(A);
124}
125
126void GRExprEngine::AddObjCMessageExprCheck(GRSimpleAPICheck* A) {
127 MsgExprChecks.push_back(A);
128}
129
Ted Kremenekf4b49df2008-02-28 10:21:43 +0000130ValueState* GRExprEngine::getInitialState() {
Ted Kremenekb5175bf2008-02-27 06:47:26 +0000131
132 // The LiveVariables information already has a compilation of all VarDecls
133 // used in the function. Iterate through this set, and "symbolicate"
134 // any VarDecl whose value originally comes from outside the function.
135
136 typedef LiveVariables::AnalysisDataTy LVDataTy;
137 LVDataTy& D = Liveness.getAnalysisData();
138
Ted Kremenekf4b49df2008-02-28 10:21:43 +0000139 ValueState StateImpl = *StateMgr.getInitialState();
Ted Kremenekb5175bf2008-02-27 06:47:26 +0000140
141 for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) {
142
Chris Lattner8c7c6a12008-06-17 18:05:57 +0000143 ScopedDecl *SD = const_cast<ScopedDecl*>(I->first);
144 if (VarDecl* VD = dyn_cast<VarDecl>(SD)) {
145 if (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD)) {
146 RVal X = RVal::GetSymbolValue(SymMgr, VD);
147 StateMgr.BindVar(StateImpl, VD, X);
148 }
149 } else if (ImplicitParamDecl *IPD = dyn_cast<ImplicitParamDecl>(SD)) {
150 RVal X = RVal::GetSymbolValue(SymMgr, IPD);
151 StateMgr.BindVar(StateImpl, IPD, X);
Ted Kremenekb5175bf2008-02-27 06:47:26 +0000152 }
Chris Lattner8c7c6a12008-06-17 18:05:57 +0000153
154
Ted Kremenekb5175bf2008-02-27 06:47:26 +0000155 }
156
157 return StateMgr.getPersistentState(StateImpl);
158}
159
Ted Kremenekf4b49df2008-02-28 10:21:43 +0000160ValueState* GRExprEngine::SetRVal(ValueState* St, Expr* Ex, RVal V) {
Ted Kremenek9b32cd02008-02-07 04:16:04 +0000161
Ted Kremenek7f5ebc72008-02-04 21:59:01 +0000162 bool isBlkExpr = false;
Ted Kremenek9b32cd02008-02-07 04:16:04 +0000163
Ted Kremenek07baa252008-02-21 18:02:17 +0000164 if (Ex == CurrentStmt) {
165 isBlkExpr = getCFG().isBlkExpr(Ex);
Ted Kremenek7f5ebc72008-02-04 21:59:01 +0000166
167 if (!isBlkExpr)
168 return St;
169 }
Ted Kremenek9b32cd02008-02-07 04:16:04 +0000170
Ted Kremenekbf573852008-04-30 04:23:07 +0000171 return StateMgr.SetRVal(St, Ex, V, isBlkExpr, true);
Ted Kremenek7f5ebc72008-02-04 21:59:01 +0000172}
173
Ted Kremenekca5f6202008-04-15 23:06:53 +0000174//===----------------------------------------------------------------------===//
175// Top-level transfer function logic (Dispatcher).
176//===----------------------------------------------------------------------===//
177
178void GRExprEngine::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
179
180 Builder = &builder;
Ted Kremenekfa7be362008-04-24 23:35:58 +0000181 EntryNode = builder.getLastNode();
Ted Kremenekca5f6202008-04-15 23:06:53 +0000182 CurrentStmt = S;
Ted Kremenekca5f6202008-04-15 23:06:53 +0000183
184 // Set up our simple checks.
185
186 // FIXME: This can probably be installed directly in GRCoreEngine, obviating
187 // the need to do a copy every time we hit a block-level statement.
188
189 if (!MsgExprChecks.empty())
190 Builder->setObjCMsgExprAuditors((GRAuditor<ValueState>**) &MsgExprChecks[0],
191 (GRAuditor<ValueState>**) (&MsgExprChecks[0] + MsgExprChecks.size()));
192
193
194 if (!CallChecks.empty())
195 Builder->setCallExprAuditors((GRAuditor<ValueState>**) &CallChecks[0],
196 (GRAuditor<ValueState>**) (&CallChecks[0] + CallChecks.size()));
197
198 // Create the cleaned state.
199
Ted Kremenekfa7be362008-04-24 23:35:58 +0000200 CleanedState = StateMgr.RemoveDeadBindings(EntryNode->getState(), CurrentStmt,
201 Liveness, DeadSymbols);
Ted Kremenekca5f6202008-04-15 23:06:53 +0000202
Ted Kremenek7487f942008-04-24 18:31:42 +0000203 // Process any special transfer function for dead symbols.
Ted Kremenekca5f6202008-04-15 23:06:53 +0000204
Ted Kremenek7487f942008-04-24 18:31:42 +0000205 NodeSet Tmp;
Ted Kremenekca5f6202008-04-15 23:06:53 +0000206
Ted Kremenek7487f942008-04-24 18:31:42 +0000207 if (DeadSymbols.empty())
Ted Kremenekfa7be362008-04-24 23:35:58 +0000208 Tmp.Add(EntryNode);
Ted Kremenek7487f942008-04-24 18:31:42 +0000209 else {
210 SaveAndRestore<bool> OldSink(Builder->BuildSinks);
Ted Kremenekfa7be362008-04-24 23:35:58 +0000211 SaveOr OldHasGen(Builder->HasGeneratedNode);
212
Ted Kremenekf05eec42008-06-18 05:34:07 +0000213 SaveAndRestore<bool> OldPurgeDeadSymbols(Builder->PurgingDeadSymbols);
214 Builder->PurgingDeadSymbols = true;
215
Ted Kremenekac91ce92008-04-25 01:25:15 +0000216 TF->EvalDeadSymbols(Tmp, *this, *Builder, EntryNode, S,
217 CleanedState, DeadSymbols);
Ted Kremenekfa7be362008-04-24 23:35:58 +0000218
219 if (!Builder->BuildSinks && !Builder->HasGeneratedNode)
220 Tmp.Add(EntryNode);
Ted Kremenek7487f942008-04-24 18:31:42 +0000221 }
Ted Kremenekfa7be362008-04-24 23:35:58 +0000222
223 bool HasAutoGenerated = false;
224
Ted Kremenek7487f942008-04-24 18:31:42 +0000225 for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
Ted Kremenekfa7be362008-04-24 23:35:58 +0000226
227 NodeSet Dst;
228
Ted Kremenek7487f942008-04-24 18:31:42 +0000229 // Set the cleaned state.
Ted Kremenekfa7be362008-04-24 23:35:58 +0000230 Builder->SetCleanedState(*I == EntryNode ? CleanedState : GetState(*I));
231
Ted Kremenek7487f942008-04-24 18:31:42 +0000232 // Visit the statement.
Ted Kremenekfa7be362008-04-24 23:35:58 +0000233 Visit(S, *I, Dst);
234
235 // Do we need to auto-generate a node? We only need to do this to generate
236 // a node with a "cleaned" state; GRCoreEngine will actually handle
237 // auto-transitions for other cases.
238 if (Dst.size() == 1 && *Dst.begin() == EntryNode
239 && !Builder->HasGeneratedNode && !HasAutoGenerated) {
240 HasAutoGenerated = true;
241 builder.generateNode(S, GetState(EntryNode), *I);
242 }
Ted Kremenek7487f942008-04-24 18:31:42 +0000243 }
Ted Kremenekca5f6202008-04-15 23:06:53 +0000244
Ted Kremenekca5f6202008-04-15 23:06:53 +0000245 // NULL out these variables to cleanup.
Ted Kremenekca5f6202008-04-15 23:06:53 +0000246 CleanedState = NULL;
Ted Kremenekfa7be362008-04-24 23:35:58 +0000247 EntryNode = NULL;
248 CurrentStmt = NULL;
249 Builder = NULL;
Ted Kremenekca5f6202008-04-15 23:06:53 +0000250}
251
252void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) {
253
254 // FIXME: add metadata to the CFG so that we can disable
255 // this check when we KNOW that there is no block-level subexpression.
256 // The motivation is that this check requires a hashtable lookup.
257
258 if (S != CurrentStmt && getCFG().isBlkExpr(S)) {
259 Dst.Add(Pred);
260 return;
261 }
262
263 switch (S->getStmtClass()) {
264
265 default:
266 // Cases we intentionally have "default" handle:
267 // AddrLabelExpr, IntegerLiteral, CharacterLiteral
268
269 Dst.Add(Pred); // No-op. Simply propagate the current state unchanged.
270 break;
Ted Kremenekbb7c1562008-04-22 04:56:29 +0000271
272 case Stmt::ArraySubscriptExprClass:
273 VisitArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst, false);
274 break;
Ted Kremenekca5f6202008-04-15 23:06:53 +0000275
276 case Stmt::AsmStmtClass:
277 VisitAsmStmt(cast<AsmStmt>(S), Pred, Dst);
278 break;
279
280 case Stmt::BinaryOperatorClass: {
281 BinaryOperator* B = cast<BinaryOperator>(S);
282
283 if (B->isLogicalOp()) {
284 VisitLogicalExpr(B, Pred, Dst);
285 break;
286 }
287 else if (B->getOpcode() == BinaryOperator::Comma) {
288 ValueState* St = GetState(Pred);
289 MakeNode(Dst, B, Pred, SetRVal(St, B, GetRVal(St, B->getRHS())));
290 break;
291 }
292
293 VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
294 break;
295 }
296
297 case Stmt::CallExprClass: {
298 CallExpr* C = cast<CallExpr>(S);
299 VisitCall(C, Pred, C->arg_begin(), C->arg_end(), Dst);
300 break;
301 }
302
303 case Stmt::CastExprClass: {
304 CastExpr* C = cast<CastExpr>(S);
305 VisitCast(C, C->getSubExpr(), Pred, Dst);
306 break;
307 }
308
309 // FIXME: ChooseExpr is really a constant. We need to fix
310 // the CFG do not model them as explicit control-flow.
311
312 case Stmt::ChooseExprClass: { // __builtin_choose_expr
313 ChooseExpr* C = cast<ChooseExpr>(S);
314 VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
315 break;
316 }
317
318 case Stmt::CompoundAssignOperatorClass:
319 VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
320 break;
321
322 case Stmt::ConditionalOperatorClass: { // '?' operator
323 ConditionalOperator* C = cast<ConditionalOperator>(S);
324 VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
325 break;
326 }
327
328 case Stmt::DeclRefExprClass:
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000329 VisitDeclRefExpr(cast<DeclRefExpr>(S), Pred, Dst, false);
Ted Kremenekca5f6202008-04-15 23:06:53 +0000330 break;
331
332 case Stmt::DeclStmtClass:
333 VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
334 break;
335
336 case Stmt::ImplicitCastExprClass: {
337 ImplicitCastExpr* C = cast<ImplicitCastExpr>(S);
338 VisitCast(C, C->getSubExpr(), Pred, Dst);
339 break;
340 }
341
Ted Kremenekd0d86202008-04-21 23:43:38 +0000342 case Stmt::MemberExprClass: {
343 VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst, false);
344 break;
345 }
346
Ted Kremenekca5f6202008-04-15 23:06:53 +0000347 case Stmt::ObjCMessageExprClass: {
348 VisitObjCMessageExpr(cast<ObjCMessageExpr>(S), Pred, Dst);
349 break;
350 }
351
352 case Stmt::ParenExprClass:
Ted Kremenekbb7c1562008-04-22 04:56:29 +0000353 Visit(cast<ParenExpr>(S)->getSubExpr()->IgnoreParens(), Pred, Dst);
Ted Kremenekca5f6202008-04-15 23:06:53 +0000354 break;
355
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000356 case Stmt::ReturnStmtClass:
357 VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst);
358 break;
359
Ted Kremenekca5f6202008-04-15 23:06:53 +0000360 case Stmt::SizeOfAlignOfTypeExprClass:
361 VisitSizeOfAlignOfTypeExpr(cast<SizeOfAlignOfTypeExpr>(S), Pred, Dst);
362 break;
363
364 case Stmt::StmtExprClass: {
365 StmtExpr* SE = cast<StmtExpr>(S);
366
367 ValueState* St = GetState(Pred);
368
369 // FIXME: Not certain if we can have empty StmtExprs. If so, we should
370 // probably just remove these from the CFG.
371 assert (!SE->getSubStmt()->body_empty());
372
373 if (Expr* LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin()))
374 MakeNode(Dst, SE, Pred, SetRVal(St, SE, GetRVal(St, LastExpr)));
375 else
376 Dst.Add(Pred);
377
378 break;
379 }
380
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000381 case Stmt::UnaryOperatorClass:
382 VisitUnaryOperator(cast<UnaryOperator>(S), Pred, Dst, false);
Ted Kremenekca5f6202008-04-15 23:06:53 +0000383 break;
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000384 }
385}
386
387void GRExprEngine::VisitLVal(Expr* Ex, NodeTy* Pred, NodeSet& Dst) {
388
389 Ex = Ex->IgnoreParens();
390
391 if (Ex != CurrentStmt && getCFG().isBlkExpr(Ex)) {
392 Dst.Add(Pred);
393 return;
394 }
395
396 switch (Ex->getStmtClass()) {
397 default:
398 Visit(Ex, Pred, Dst);
399 return;
400
401 case Stmt::ArraySubscriptExprClass:
402 VisitArraySubscriptExpr(cast<ArraySubscriptExpr>(Ex), Pred, Dst, true);
403 return;
404
405 case Stmt::DeclRefExprClass:
406 VisitDeclRefExpr(cast<DeclRefExpr>(Ex), Pred, Dst, true);
407 return;
408
409 case Stmt::UnaryOperatorClass:
410 VisitUnaryOperator(cast<UnaryOperator>(Ex), Pred, Dst, true);
411 return;
412
413 case Stmt::MemberExprClass:
414 VisitMemberExpr(cast<MemberExpr>(Ex), Pred, Dst, true);
415 return;
Ted Kremenekca5f6202008-04-15 23:06:53 +0000416 }
417}
418
419//===----------------------------------------------------------------------===//
420// Block entrance. (Update counters).
421//===----------------------------------------------------------------------===//
422
423bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, ValueState*,
424 GRBlockCounter BC) {
425
426 return BC.getNumVisited(B->getBlockID()) < 3;
427}
428
429//===----------------------------------------------------------------------===//
430// Branch processing.
431//===----------------------------------------------------------------------===//
432
Ted Kremenekf4b49df2008-02-28 10:21:43 +0000433ValueState* GRExprEngine::MarkBranch(ValueState* St, Stmt* Terminator,
434 bool branchTaken) {
Ted Kremenek99ecce72008-02-26 19:05:15 +0000435
436 switch (Terminator->getStmtClass()) {
437 default:
438 return St;
439
440 case Stmt::BinaryOperatorClass: { // '&&' and '||'
441
442 BinaryOperator* B = cast<BinaryOperator>(Terminator);
443 BinaryOperator::Opcode Op = B->getOpcode();
444
445 assert (Op == BinaryOperator::LAnd || Op == BinaryOperator::LOr);
446
447 // For &&, if we take the true branch, then the value of the whole
448 // expression is that of the RHS expression.
449 //
450 // For ||, if we take the false branch, then the value of the whole
451 // expression is that of the RHS expression.
452
453 Expr* Ex = (Op == BinaryOperator::LAnd && branchTaken) ||
454 (Op == BinaryOperator::LOr && !branchTaken)
455 ? B->getRHS() : B->getLHS();
456
Ted Kremenekb31af242008-02-28 09:25:22 +0000457 return SetBlkExprRVal(St, B, UndefinedVal(Ex));
Ted Kremenek99ecce72008-02-26 19:05:15 +0000458 }
459
460 case Stmt::ConditionalOperatorClass: { // ?:
461
462 ConditionalOperator* C = cast<ConditionalOperator>(Terminator);
463
464 // For ?, if branchTaken == true then the value is either the LHS or
465 // the condition itself. (GNU extension).
466
467 Expr* Ex;
468
469 if (branchTaken)
470 Ex = C->getLHS() ? C->getLHS() : C->getCond();
471 else
472 Ex = C->getRHS();
473
Ted Kremenekb31af242008-02-28 09:25:22 +0000474 return SetBlkExprRVal(St, C, UndefinedVal(Ex));
Ted Kremenek99ecce72008-02-26 19:05:15 +0000475 }
476
477 case Stmt::ChooseExprClass: { // ?:
478
479 ChooseExpr* C = cast<ChooseExpr>(Terminator);
480
481 Expr* Ex = branchTaken ? C->getLHS() : C->getRHS();
Ted Kremenekb31af242008-02-28 09:25:22 +0000482 return SetBlkExprRVal(St, C, UndefinedVal(Ex));
Ted Kremenek99ecce72008-02-26 19:05:15 +0000483 }
484 }
485}
486
Ted Kremenek30fa28b2008-02-13 17:41:41 +0000487void GRExprEngine::ProcessBranch(Expr* Condition, Stmt* Term,
Ted Kremenek07baa252008-02-21 18:02:17 +0000488 BranchNodeBuilder& builder) {
Ted Kremenek90960972008-01-30 23:03:39 +0000489
Ted Kremenek17c5f112008-02-11 19:21:59 +0000490 // Remove old bindings for subexpressions.
Ted Kremenekf4b49df2008-02-28 10:21:43 +0000491 ValueState* PrevState = StateMgr.RemoveSubExprBindings(builder.getState());
Ted Kremenek1f0eb992008-02-05 00:26:40 +0000492
Ted Kremenek022b6052008-02-15 22:29:00 +0000493 // Check for NULL conditions; e.g. "for(;;)"
494 if (!Condition) {
495 builder.markInfeasible(false);
Ted Kremenek022b6052008-02-15 22:29:00 +0000496 return;
497 }
498
Ted Kremenek07baa252008-02-21 18:02:17 +0000499 RVal V = GetRVal(PrevState, Condition);
Ted Kremenek90960972008-01-30 23:03:39 +0000500
501 switch (V.getBaseKind()) {
502 default:
503 break;
504
Ted Kremenek07baa252008-02-21 18:02:17 +0000505 case RVal::UnknownKind:
Ted Kremenek5f2eb192008-02-26 19:40:44 +0000506 builder.generateNode(MarkBranch(PrevState, Term, true), true);
507 builder.generateNode(MarkBranch(PrevState, Term, false), false);
Ted Kremenek90960972008-01-30 23:03:39 +0000508 return;
509
Ted Kremenekb31af242008-02-28 09:25:22 +0000510 case RVal::UndefinedKind: {
Ted Kremenek90960972008-01-30 23:03:39 +0000511 NodeTy* N = builder.generateNode(PrevState, true);
512
513 if (N) {
514 N->markAsSink();
Ted Kremenekb31af242008-02-28 09:25:22 +0000515 UndefBranches.insert(N);
Ted Kremenek90960972008-01-30 23:03:39 +0000516 }
517
518 builder.markInfeasible(false);
519 return;
520 }
521 }
Ted Kremenek4b170e52008-02-12 18:08:17 +0000522
Ted Kremenek5c6eeb12008-02-29 20:27:50 +0000523 // Process the true branch.
Ted Kremenek4b170e52008-02-12 18:08:17 +0000524
Ted Kremenekd4676512008-03-12 21:45:47 +0000525 bool isFeasible = false;
Ted Kremenek5c6eeb12008-02-29 20:27:50 +0000526 ValueState* St = Assume(PrevState, V, true, isFeasible);
527
528 if (isFeasible)
529 builder.generateNode(MarkBranch(St, Term, true), true);
Ted Kremenek4b170e52008-02-12 18:08:17 +0000530 else
531 builder.markInfeasible(true);
Ted Kremenek5c6eeb12008-02-29 20:27:50 +0000532
533 // Process the false branch.
Ted Kremenek90960972008-01-30 23:03:39 +0000534
Ted Kremenek5c6eeb12008-02-29 20:27:50 +0000535 isFeasible = false;
536 St = Assume(PrevState, V, false, isFeasible);
Ted Kremenek90960972008-01-30 23:03:39 +0000537
Ted Kremenek5c6eeb12008-02-29 20:27:50 +0000538 if (isFeasible)
539 builder.generateNode(MarkBranch(St, Term, false), false);
Ted Kremenek1f0eb992008-02-05 00:26:40 +0000540 else
541 builder.markInfeasible(false);
Ted Kremenek6ff3cea2008-01-29 23:32:35 +0000542}
543
Ted Kremenek30fa28b2008-02-13 17:41:41 +0000544/// ProcessIndirectGoto - Called by GRCoreEngine. Used to generate successor
Ted Kremenek677f4ef2008-02-13 00:24:44 +0000545/// nodes by processing the 'effects' of a computed goto jump.
Ted Kremenek30fa28b2008-02-13 17:41:41 +0000546void GRExprEngine::ProcessIndirectGoto(IndirectGotoNodeBuilder& builder) {
Ted Kremenek677f4ef2008-02-13 00:24:44 +0000547
Ted Kremenekf4b49df2008-02-28 10:21:43 +0000548 ValueState* St = builder.getState();
Ted Kremenek07baa252008-02-21 18:02:17 +0000549 RVal V = GetRVal(St, builder.getTarget());
Ted Kremenek677f4ef2008-02-13 00:24:44 +0000550
551 // Three possibilities:
552 //
553 // (1) We know the computed label.
Ted Kremenekb31af242008-02-28 09:25:22 +0000554 // (2) The label is NULL (or some other constant), or Undefined.
Ted Kremenek677f4ef2008-02-13 00:24:44 +0000555 // (3) We have no clue about the label. Dispatch to all targets.
556 //
557
558 typedef IndirectGotoNodeBuilder::iterator iterator;
559
560 if (isa<lval::GotoLabel>(V)) {
561 LabelStmt* L = cast<lval::GotoLabel>(V).getLabel();
562
563 for (iterator I=builder.begin(), E=builder.end(); I != E; ++I) {
Ted Kremenek79f63f52008-02-13 17:27:37 +0000564 if (I.getLabel() == L) {
565 builder.generateNode(I, St);
Ted Kremenek677f4ef2008-02-13 00:24:44 +0000566 return;
567 }
568 }
569
570 assert (false && "No block with label.");
571 return;
572 }
573
Ted Kremenekb31af242008-02-28 09:25:22 +0000574 if (isa<lval::ConcreteInt>(V) || isa<UndefinedVal>(V)) {
Ted Kremenek677f4ef2008-02-13 00:24:44 +0000575 // Dispatch to the first target and mark it as a sink.
Ted Kremenek79f63f52008-02-13 17:27:37 +0000576 NodeTy* N = builder.generateNode(builder.begin(), St, true);
Ted Kremenekb31af242008-02-28 09:25:22 +0000577 UndefBranches.insert(N);
Ted Kremenek677f4ef2008-02-13 00:24:44 +0000578 return;
579 }
580
581 // This is really a catch-all. We don't support symbolics yet.
582
Ted Kremenek07baa252008-02-21 18:02:17 +0000583 assert (V.isUnknown());
Ted Kremenek677f4ef2008-02-13 00:24:44 +0000584
585 for (iterator I=builder.begin(), E=builder.end(); I != E; ++I)
Ted Kremenek79f63f52008-02-13 17:27:37 +0000586 builder.generateNode(I, St);
Ted Kremenek677f4ef2008-02-13 00:24:44 +0000587}
Ted Kremenek1f0eb992008-02-05 00:26:40 +0000588
Ted Kremenekca5f6202008-04-15 23:06:53 +0000589
590void GRExprEngine::VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R,
591 NodeTy* Pred, NodeSet& Dst) {
592
593 assert (Ex == CurrentStmt && getCFG().isBlkExpr(Ex));
594
595 ValueState* St = GetState(Pred);
596 RVal X = GetBlkExprRVal(St, Ex);
597
598 assert (X.isUndef());
599
600 Expr* SE = (Expr*) cast<UndefinedVal>(X).getData();
601
602 assert (SE);
603
604 X = GetBlkExprRVal(St, SE);
605
606 // Make sure that we invalidate the previous binding.
607 MakeNode(Dst, Ex, Pred, StateMgr.SetRVal(St, Ex, X, true, true));
608}
609
Ted Kremenekaee121c2008-02-13 23:08:21 +0000610/// ProcessSwitch - Called by GRCoreEngine. Used to generate successor
611/// nodes by processing the 'effects' of a switch statement.
612void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) {
613
614 typedef SwitchNodeBuilder::iterator iterator;
615
Ted Kremenekf4b49df2008-02-28 10:21:43 +0000616 ValueState* St = builder.getState();
Ted Kremenekbc965a62008-02-18 22:57:02 +0000617 Expr* CondE = builder.getCondition();
Ted Kremenek07baa252008-02-21 18:02:17 +0000618 RVal CondV = GetRVal(St, CondE);
Ted Kremenekaee121c2008-02-13 23:08:21 +0000619
Ted Kremenekb31af242008-02-28 09:25:22 +0000620 if (CondV.isUndef()) {
Ted Kremenekaee121c2008-02-13 23:08:21 +0000621 NodeTy* N = builder.generateDefaultCaseNode(St, true);
Ted Kremenekb31af242008-02-28 09:25:22 +0000622 UndefBranches.insert(N);
Ted Kremenekaee121c2008-02-13 23:08:21 +0000623 return;
624 }
625
Ted Kremenekf4b49df2008-02-28 10:21:43 +0000626 ValueState* DefaultSt = St;
Ted Kremenekaee121c2008-02-13 23:08:21 +0000627
628 // While most of this can be assumed (such as the signedness), having it
629 // just computed makes sure everything makes the same assumptions end-to-end.
Ted Kremenekbc965a62008-02-18 22:57:02 +0000630
Chris Lattner8cd0e932008-03-05 18:54:05 +0000631 unsigned bits = getContext().getTypeSize(CondE->getType());
Ted Kremenekbc965a62008-02-18 22:57:02 +0000632
Ted Kremenekaee121c2008-02-13 23:08:21 +0000633 APSInt V1(bits, false);
634 APSInt V2 = V1;
Ted Kremenekdf3aaa12008-04-23 05:03:18 +0000635 bool DefaultFeasible = false;
Ted Kremenekaee121c2008-02-13 23:08:21 +0000636
Ted Kremenek07baa252008-02-21 18:02:17 +0000637 for (iterator I = builder.begin(), EI = builder.end(); I != EI; ++I) {
Ted Kremenekaee121c2008-02-13 23:08:21 +0000638
639 CaseStmt* Case = cast<CaseStmt>(I.getCase());
640
641 // Evaluate the case.
642 if (!Case->getLHS()->isIntegerConstantExpr(V1, getContext(), 0, true)) {
643 assert (false && "Case condition must evaluate to an integer constant.");
644 return;
645 }
646
647 // Get the RHS of the case, if it exists.
648
649 if (Expr* E = Case->getRHS()) {
650 if (!E->isIntegerConstantExpr(V2, getContext(), 0, true)) {
651 assert (false &&
652 "Case condition (RHS) must evaluate to an integer constant.");
653 return ;
654 }
655
656 assert (V1 <= V2);
657 }
Ted Kremenekf1d623e2008-03-17 22:17:56 +0000658 else
659 V2 = V1;
Ted Kremenekaee121c2008-02-13 23:08:21 +0000660
661 // FIXME: Eventually we should replace the logic below with a range
662 // comparison, rather than concretize the values within the range.
Ted Kremenek07baa252008-02-21 18:02:17 +0000663 // This should be easy once we have "ranges" for NonLVals.
Ted Kremenekaee121c2008-02-13 23:08:21 +0000664
Ted Kremenekf1d623e2008-03-17 22:17:56 +0000665 do {
Ted Kremenek8ad19872008-03-07 20:13:31 +0000666 nonlval::ConcreteInt CaseVal(BasicVals.getValue(V1));
Ted Kremenekaee121c2008-02-13 23:08:21 +0000667
Ted Kremenek07baa252008-02-21 18:02:17 +0000668 RVal Res = EvalBinOp(BinaryOperator::EQ, CondV, CaseVal);
Ted Kremenekaee121c2008-02-13 23:08:21 +0000669
670 // Now "assume" that the case matches.
Ted Kremenekaee121c2008-02-13 23:08:21 +0000671
Ted Kremenekd4676512008-03-12 21:45:47 +0000672 bool isFeasible = false;
Ted Kremenekf4b49df2008-02-28 10:21:43 +0000673 ValueState* StNew = Assume(St, Res, true, isFeasible);
Ted Kremenekaee121c2008-02-13 23:08:21 +0000674
675 if (isFeasible) {
676 builder.generateCaseStmtNode(I, StNew);
677
678 // If CondV evaluates to a constant, then we know that this
679 // is the *only* case that we can take, so stop evaluating the
680 // others.
681 if (isa<nonlval::ConcreteInt>(CondV))
682 return;
683 }
684
685 // Now "assume" that the case doesn't match. Add this state
686 // to the default state (if it is feasible).
687
Ted Kremenekd4676512008-03-12 21:45:47 +0000688 isFeasible = false;
Ted Kremenekb1934132008-02-14 19:37:24 +0000689 StNew = Assume(DefaultSt, Res, false, isFeasible);
Ted Kremenekaee121c2008-02-13 23:08:21 +0000690
Ted Kremenekdf3aaa12008-04-23 05:03:18 +0000691 if (isFeasible) {
692 DefaultFeasible = true;
Ted Kremenekaee121c2008-02-13 23:08:21 +0000693 DefaultSt = StNew;
Ted Kremenekdf3aaa12008-04-23 05:03:18 +0000694 }
Ted Kremenekaee121c2008-02-13 23:08:21 +0000695
Ted Kremenekf1d623e2008-03-17 22:17:56 +0000696 // Concretize the next value in the range.
697 if (V1 == V2)
698 break;
Ted Kremenekaee121c2008-02-13 23:08:21 +0000699
Ted Kremenekf1d623e2008-03-17 22:17:56 +0000700 ++V1;
Ted Kremenek539269c2008-03-17 22:18:22 +0000701 assert (V1 <= V2);
Ted Kremenekf1d623e2008-03-17 22:17:56 +0000702
703 } while (true);
Ted Kremenekaee121c2008-02-13 23:08:21 +0000704 }
705
706 // If we reach here, than we know that the default branch is
707 // possible.
Ted Kremenekdf3aaa12008-04-23 05:03:18 +0000708 if (DefaultFeasible) builder.generateDefaultCaseNode(DefaultSt);
Ted Kremenekaee121c2008-02-13 23:08:21 +0000709}
710
Ted Kremenekca5f6202008-04-15 23:06:53 +0000711//===----------------------------------------------------------------------===//
712// Transfer functions: logical operations ('&&', '||').
713//===----------------------------------------------------------------------===//
Ted Kremenekaee121c2008-02-13 23:08:21 +0000714
Ted Kremenek30fa28b2008-02-13 17:41:41 +0000715void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred,
Ted Kremenek07baa252008-02-21 18:02:17 +0000716 NodeSet& Dst) {
Ted Kremenekbf988d02008-02-19 00:22:37 +0000717
Ted Kremenek99ecce72008-02-26 19:05:15 +0000718 assert (B->getOpcode() == BinaryOperator::LAnd ||
719 B->getOpcode() == BinaryOperator::LOr);
720
721 assert (B == CurrentStmt && getCFG().isBlkExpr(B));
722
Ted Kremenek50ef5ff2008-03-10 04:11:42 +0000723 ValueState* St = GetState(Pred);
Ted Kremenek99ecce72008-02-26 19:05:15 +0000724 RVal X = GetBlkExprRVal(St, B);
725
Ted Kremenekb31af242008-02-28 09:25:22 +0000726 assert (X.isUndef());
Ted Kremenek99ecce72008-02-26 19:05:15 +0000727
Ted Kremenekb31af242008-02-28 09:25:22 +0000728 Expr* Ex = (Expr*) cast<UndefinedVal>(X).getData();
Ted Kremenek99ecce72008-02-26 19:05:15 +0000729
730 assert (Ex);
731
732 if (Ex == B->getRHS()) {
733
734 X = GetBlkExprRVal(St, Ex);
735
Ted Kremenekb31af242008-02-28 09:25:22 +0000736 // Handle undefined values.
Ted Kremenek5f2eb192008-02-26 19:40:44 +0000737
Ted Kremenekb31af242008-02-28 09:25:22 +0000738 if (X.isUndef()) {
Ted Kremenekf10f2882008-03-21 21:30:14 +0000739 MakeNode(Dst, B, Pred, SetBlkExprRVal(St, B, X));
Ted Kremenek5f2eb192008-02-26 19:40:44 +0000740 return;
741 }
742
Ted Kremenek99ecce72008-02-26 19:05:15 +0000743 // We took the RHS. Because the value of the '&&' or '||' expression must
744 // evaluate to 0 or 1, we must assume the value of the RHS evaluates to 0
745 // or 1. Alternatively, we could take a lazy approach, and calculate this
746 // value later when necessary. We don't have the machinery in place for
747 // this right now, and since most logical expressions are used for branches,
748 // the payoff is not likely to be large. Instead, we do eager evaluation.
749
750 bool isFeasible = false;
Ted Kremenekf4b49df2008-02-28 10:21:43 +0000751 ValueState* NewState = Assume(St, X, true, isFeasible);
Ted Kremenek99ecce72008-02-26 19:05:15 +0000752
753 if (isFeasible)
Ted Kremenekf10f2882008-03-21 21:30:14 +0000754 MakeNode(Dst, B, Pred,
755 SetBlkExprRVal(NewState, B, MakeConstantVal(1U, B)));
Ted Kremenek99ecce72008-02-26 19:05:15 +0000756
757 isFeasible = false;
758 NewState = Assume(St, X, false, isFeasible);
759
760 if (isFeasible)
Ted Kremenekf10f2882008-03-21 21:30:14 +0000761 MakeNode(Dst, B, Pred,
762 SetBlkExprRVal(NewState, B, MakeConstantVal(0U, B)));
Ted Kremenek1f0eb992008-02-05 00:26:40 +0000763 }
764 else {
Ted Kremenek99ecce72008-02-26 19:05:15 +0000765 // We took the LHS expression. Depending on whether we are '&&' or
766 // '||' we know what the value of the expression is via properties of
767 // the short-circuiting.
768
769 X = MakeConstantVal( B->getOpcode() == BinaryOperator::LAnd ? 0U : 1U, B);
Ted Kremenekf10f2882008-03-21 21:30:14 +0000770 MakeNode(Dst, B, Pred, SetBlkExprRVal(St, B, X));
Ted Kremenek1f0eb992008-02-05 00:26:40 +0000771 }
Ted Kremenek1f0eb992008-02-05 00:26:40 +0000772}
Ted Kremenek99ecce72008-02-26 19:05:15 +0000773
Ted Kremenekca5f6202008-04-15 23:06:53 +0000774//===----------------------------------------------------------------------===//
Ted Kremenek4d22f0e2008-04-16 18:39:06 +0000775// Transfer functions: Loads and stores.
Ted Kremenekca5f6202008-04-15 23:06:53 +0000776//===----------------------------------------------------------------------===//
Ted Kremenek68d70a82008-01-15 23:55:06 +0000777
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000778void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* D, NodeTy* Pred, NodeSet& Dst,
779 bool asLVal) {
Ted Kremenek9b32cd02008-02-07 04:16:04 +0000780
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000781 ValueState* St = GetState(Pred);
Ted Kremenekf97c6682008-03-09 03:30:59 +0000782 RVal X = RVal::MakeVal(BasicVals, D);
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000783
784 if (asLVal)
785 MakeNode(Dst, D, Pred, SetRVal(St, D, cast<LVal>(X)));
786 else {
787 RVal V = isa<lval::DeclVal>(X) ? GetRVal(St, cast<LVal>(X)) : X;
788 MakeNode(Dst, D, Pred, SetRVal(St, D, V));
789 }
Ted Kremenek9b32cd02008-02-07 04:16:04 +0000790}
791
Ted Kremenekbb7c1562008-04-22 04:56:29 +0000792/// VisitArraySubscriptExpr - Transfer function for array accesses
793void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A, NodeTy* Pred,
794 NodeSet& Dst, bool asLVal) {
795
796 Expr* Base = A->getBase()->IgnoreParens();
Ted Kremenekc4385b42008-04-29 23:24:44 +0000797 Expr* Idx = A->getIdx()->IgnoreParens();
Ted Kremenekbb7c1562008-04-22 04:56:29 +0000798
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000799 // Always visit the base as an LVal expression. This computes the
800 // abstract address of the base object.
801 NodeSet Tmp;
Ted Kremenekbb7c1562008-04-22 04:56:29 +0000802
Ted Kremenek9e2c1ea2008-05-09 23:45:33 +0000803 if (LVal::IsLValType(Base->getType())) // Base always is an LVal.
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000804 Visit(Base, Pred, Tmp);
805 else
806 VisitLVal(Base, Pred, Tmp);
807
Ted Kremenekc4385b42008-04-29 23:24:44 +0000808 for (NodeSet::iterator I1=Tmp.begin(), E1=Tmp.end(); I1!=E1; ++I1) {
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000809
Ted Kremenekc4385b42008-04-29 23:24:44 +0000810 // Evaluate the index.
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000811
Ted Kremenekc4385b42008-04-29 23:24:44 +0000812 NodeSet Tmp2;
813 Visit(Idx, *I1, Tmp2);
814
815 for (NodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end(); I2!=E2; ++I2) {
816
817 ValueState* St = GetState(*I2);
818 RVal BaseV = GetRVal(St, Base);
819 RVal IdxV = GetRVal(St, Idx);
Ted Kremenekb4aecd02008-04-30 21:05:35 +0000820
821 // If IdxV is 0, return just BaseV.
822
823 bool useBase = false;
824
825 if (nonlval::ConcreteInt* IdxInt = dyn_cast<nonlval::ConcreteInt>(&IdxV))
826 useBase = IdxInt->getValue() == 0;
827
828 RVal V = useBase ? BaseV : lval::ArrayOffset::Make(BasicVals, BaseV,IdxV);
Ted Kremenekc4385b42008-04-29 23:24:44 +0000829
830 if (asLVal)
831 MakeNode(Dst, A, *I2, SetRVal(St, A, V));
832 else
833 EvalLoad(Dst, A, *I2, St, V);
834 }
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000835 }
Ted Kremenekbb7c1562008-04-22 04:56:29 +0000836}
837
Ted Kremenekd0d86202008-04-21 23:43:38 +0000838/// VisitMemberExpr - Transfer function for member expressions.
839void GRExprEngine::VisitMemberExpr(MemberExpr* M, NodeTy* Pred,
840 NodeSet& Dst, bool asLVal) {
841
842 Expr* Base = M->getBase()->IgnoreParens();
843
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000844 // Always visit the base as an LVal expression. This computes the
845 // abstract address of the base object.
Ted Kremenekd0d86202008-04-21 23:43:38 +0000846 NodeSet Tmp;
Ted Kremenekd0d86202008-04-21 23:43:38 +0000847
Ted Kremenekc59a8e72008-04-30 22:17:15 +0000848 if (asLVal) {
849
Ted Kremenek9e2c1ea2008-05-09 23:45:33 +0000850 if (LVal::IsLValType(Base->getType())) // Base always is an LVal.
Ted Kremenekc59a8e72008-04-30 22:17:15 +0000851 Visit(Base, Pred, Tmp);
852 else
853 VisitLVal(Base, Pred, Tmp);
854
855 for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
856 ValueState* St = GetState(*I);
857 RVal BaseV = GetRVal(St, Base);
858
859 RVal V = lval::FieldOffset::Make(BasicVals, GetRVal(St, Base),
860 M->getMemberDecl());
861
862 MakeNode(Dst, M, *I, SetRVal(St, M, V));
863 }
864
865 return;
866 }
867
868 // Evaluate the base. Can be an LVal or NonLVal (depends on whether
869 // or not isArrow() is true).
870 Visit(Base, Pred, Tmp);
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000871
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000872 for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
Ted Kremenekc59a8e72008-04-30 22:17:15 +0000873
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000874 ValueState* St = GetState(*I);
Ted Kremenekc59a8e72008-04-30 22:17:15 +0000875 RVal BaseV = GetRVal(St, Base);
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000876
Ted Kremenek9e2c1ea2008-05-09 23:45:33 +0000877 if (LVal::IsLValType(Base->getType())) {
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000878
Ted Kremenekc59a8e72008-04-30 22:17:15 +0000879 assert (M->isArrow());
880
881 RVal V = lval::FieldOffset::Make(BasicVals, GetRVal(St, Base),
882 M->getMemberDecl());
883
Ted Kremenekc4385b42008-04-29 23:24:44 +0000884 EvalLoad(Dst, M, *I, St, V);
Ted Kremenekc59a8e72008-04-30 22:17:15 +0000885 }
886 else {
887
888 assert (!M->isArrow());
889
890 if (BaseV.isUnknownOrUndef()) {
891 MakeNode(Dst, M, *I, SetRVal(St, M, BaseV));
892 continue;
893 }
894
895 // FIXME: Implement nonlval objects representing struct temporaries.
896 assert (isa<NonLVal>(BaseV));
897 MakeNode(Dst, M, *I, SetRVal(St, M, UnknownVal()));
898 }
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000899 }
Ted Kremenekd0d86202008-04-21 23:43:38 +0000900}
901
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000902void GRExprEngine::EvalStore(NodeSet& Dst, Expr* Ex, NodeTy* Pred,
903 ValueState* St, RVal location, RVal Val) {
Ted Kremenek4d22f0e2008-04-16 18:39:06 +0000904
905 assert (Builder && "GRStmtNodeBuilder must be defined.");
906
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000907 // Evaluate the location (checks for bad dereferences).
908 St = EvalLocation(Ex, Pred, St, location);
909
910 if (!St)
911 return;
912
913 // Proceed with the store.
914
Ted Kremenek4d22f0e2008-04-16 18:39:06 +0000915 unsigned size = Dst.size();
Ted Kremenek0b03c6e2008-04-18 20:35:30 +0000916
Ted Kremenek0a6a80b2008-04-23 20:12:28 +0000917 SaveAndRestore<bool> OldSink(Builder->BuildSinks);
918 SaveOr OldHasGen(Builder->HasGeneratedNode);
Ted Kremenek0b03c6e2008-04-18 20:35:30 +0000919
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000920 assert (!location.isUndef());
Ted Kremenek7aef4842008-04-16 20:40:59 +0000921
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000922 TF->EvalStore(Dst, *this, *Builder, Ex, Pred, St, location, Val);
Ted Kremenek4d22f0e2008-04-16 18:39:06 +0000923
924 // Handle the case where no nodes where generated. Auto-generate that
925 // contains the updated state if we aren't generating sinks.
926
Ted Kremenek0b03c6e2008-04-18 20:35:30 +0000927 if (!Builder->BuildSinks && Dst.size() == size && !Builder->HasGeneratedNode)
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000928 TF->GRTransferFuncs::EvalStore(Dst, *this, *Builder, Ex, Pred, St,
929 location, Val);
930}
931
932void GRExprEngine::EvalLoad(NodeSet& Dst, Expr* Ex, NodeTy* Pred,
933 ValueState* St, RVal location, bool CheckOnly) {
934
935 // Evaluate the location (checks for bad dereferences).
936
937 St = EvalLocation(Ex, Pred, St, location, true);
938
939 if (!St)
940 return;
941
942 // Proceed with the load.
943
944 // FIXME: Currently symbolic analysis "generates" new symbols
945 // for the contents of values. We need a better approach.
946
947 // FIXME: The "CheckOnly" option exists only because Array and Field
948 // loads aren't fully implemented. Eventually this option will go away.
949
Ted Kremenekbf573852008-04-30 04:23:07 +0000950 if (CheckOnly)
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000951 MakeNode(Dst, Ex, Pred, St);
Ted Kremenekbf573852008-04-30 04:23:07 +0000952 else if (location.isUnknown()) {
953 // This is important. We must nuke the old binding.
954 MakeNode(Dst, Ex, Pred, SetRVal(St, Ex, UnknownVal()));
955 }
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000956 else
957 MakeNode(Dst, Ex, Pred, SetRVal(St, Ex, GetRVal(St, cast<LVal>(location),
958 Ex->getType())));
959}
960
961ValueState* GRExprEngine::EvalLocation(Expr* Ex, NodeTy* Pred,
962 ValueState* St, RVal location,
963 bool isLoad) {
964
965 // Check for loads/stores from/to undefined values.
966 if (location.isUndef()) {
Ted Kremenekf05eec42008-06-18 05:34:07 +0000967 ProgramPoint::Kind K =
968 isLoad ? ProgramPoint::PostLoadKind : ProgramPoint::PostStmtKind;
969
970 if (NodeTy* Succ = Builder->generateNode(Ex, St, Pred, K)) {
Ted Kremenek5f6b4422008-04-29 21:04:26 +0000971 Succ->markAsSink();
972 UndefDeref.insert(Succ);
973 }
974
975 return NULL;
976 }
977
978 // Check for loads/stores from/to unknown locations. Treat as No-Ops.
979 if (location.isUnknown())
980 return St;
981
982 // During a load, one of two possible situations arise:
983 // (1) A crash, because the location (pointer) was NULL.
984 // (2) The location (pointer) is not NULL, and the dereference works.
985 //
986 // We add these assumptions.
987
988 LVal LV = cast<LVal>(location);
989
990 // "Assume" that the pointer is not NULL.
991
992 bool isFeasibleNotNull = false;
993 ValueState* StNotNull = Assume(St, LV, true, isFeasibleNotNull);
994
995 // "Assume" that the pointer is NULL.
996
997 bool isFeasibleNull = false;
998 ValueState* StNull = Assume(St, LV, false, isFeasibleNull);
999
1000 if (isFeasibleNull) {
1001
1002 // We don't use "MakeNode" here because the node will be a sink
1003 // and we have no intention of processing it later.
1004
Ted Kremenekf05eec42008-06-18 05:34:07 +00001005 ProgramPoint::Kind K =
1006 isLoad ? ProgramPoint::PostLoadKind : ProgramPoint::PostStmtKind;
1007
1008 NodeTy* NullNode = Builder->generateNode(Ex, StNull, Pred, K);
Ted Kremenek5f6b4422008-04-29 21:04:26 +00001009
1010 if (NullNode) {
1011
1012 NullNode->markAsSink();
1013
1014 if (isFeasibleNotNull) ImplicitNullDeref.insert(NullNode);
1015 else ExplicitNullDeref.insert(NullNode);
1016 }
1017 }
1018
1019 return isFeasibleNotNull ? StNotNull : NULL;
Ted Kremenek4d22f0e2008-04-16 18:39:06 +00001020}
1021
Ted Kremenekca5f6202008-04-15 23:06:53 +00001022//===----------------------------------------------------------------------===//
1023// Transfer function: Function calls.
1024//===----------------------------------------------------------------------===//
1025
Ted Kremenekd9268e32008-02-19 01:44:53 +00001026void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
Ted Kremenek07baa252008-02-21 18:02:17 +00001027 CallExpr::arg_iterator AI,
1028 CallExpr::arg_iterator AE,
Ted Kremenekd9268e32008-02-19 01:44:53 +00001029 NodeSet& Dst) {
1030
Ted Kremenek07baa252008-02-21 18:02:17 +00001031 // Process the arguments.
1032
1033 if (AI != AE) {
Ted Kremenekd9268e32008-02-19 01:44:53 +00001034
Ted Kremenekef7ea072008-03-04 00:56:45 +00001035 NodeSet DstTmp;
Ted Kremenek769f3482008-03-04 22:01:56 +00001036 Visit(*AI, Pred, DstTmp);
Ted Kremenek07baa252008-02-21 18:02:17 +00001037 ++AI;
1038
Ted Kremenek769f3482008-03-04 22:01:56 +00001039 for (NodeSet::iterator DI=DstTmp.begin(), DE=DstTmp.end(); DI != DE; ++DI)
Ted Kremenek07baa252008-02-21 18:02:17 +00001040 VisitCall(CE, *DI, AI, AE, Dst);
Ted Kremenekd9268e32008-02-19 01:44:53 +00001041
1042 return;
1043 }
1044
1045 // If we reach here we have processed all of the arguments. Evaluate
1046 // the callee expression.
Ted Kremenekcda2efd2008-03-03 16:47:31 +00001047
Ted Kremenekc71901d2008-02-25 21:16:03 +00001048 NodeSet DstTmp;
Ted Kremenek0a6a80b2008-04-23 20:12:28 +00001049 Expr* Callee = CE->getCallee()->IgnoreParens();
Ted Kremenekcda2efd2008-03-03 16:47:31 +00001050
Ted Kremenekc71901d2008-02-25 21:16:03 +00001051 VisitLVal(Callee, Pred, DstTmp);
Ted Kremenekcda2efd2008-03-03 16:47:31 +00001052
Ted Kremenekd9268e32008-02-19 01:44:53 +00001053 // Finally, evaluate the function call.
Ted Kremenek07baa252008-02-21 18:02:17 +00001054 for (NodeSet::iterator DI = DstTmp.begin(), DE = DstTmp.end(); DI!=DE; ++DI) {
1055
Ted Kremenek50ef5ff2008-03-10 04:11:42 +00001056 ValueState* St = GetState(*DI);
Ted Kremenek5f6b4422008-04-29 21:04:26 +00001057 RVal L = GetRVal(St, Callee);
Ted Kremenekd9268e32008-02-19 01:44:53 +00001058
Ted Kremenekcda2efd2008-03-03 16:47:31 +00001059 // FIXME: Add support for symbolic function calls (calls involving
1060 // function pointer values that are symbolic).
1061
1062 // Check for undefined control-flow or calls to NULL.
1063
Ted Kremenek43863eb2008-02-29 23:14:48 +00001064 if (L.isUndef() || isa<lval::ConcreteInt>(L)) {
Ted Kremenekd9268e32008-02-19 01:44:53 +00001065 NodeTy* N = Builder->generateNode(CE, St, *DI);
Ted Kremenek769f3482008-03-04 22:01:56 +00001066
Ted Kremenek9b31f5b2008-02-29 23:53:11 +00001067 if (N) {
1068 N->markAsSink();
1069 BadCalls.insert(N);
1070 }
Ted Kremenek769f3482008-03-04 22:01:56 +00001071
Ted Kremenekd9268e32008-02-19 01:44:53 +00001072 continue;
Ted Kremenekb451dd32008-03-05 21:15:02 +00001073 }
1074
1075 // Check for the "noreturn" attribute.
1076
1077 SaveAndRestore<bool> OldSink(Builder->BuildSinks);
1078
Ted Kremenek02b1ff72008-03-14 21:58:42 +00001079 if (isa<lval::FuncVal>(L)) {
1080
1081 FunctionDecl* FD = cast<lval::FuncVal>(L).getDecl();
1082
1083 if (FD->getAttr<NoReturnAttr>())
Ted Kremenekb451dd32008-03-05 21:15:02 +00001084 Builder->BuildSinks = true;
Ted Kremenek02b1ff72008-03-14 21:58:42 +00001085 else {
1086 // HACK: Some functions are not marked noreturn, and don't return.
1087 // Here are a few hardwired ones. If this takes too long, we can
1088 // potentially cache these results.
1089 const char* s = FD->getIdentifier()->getName();
1090 unsigned n = strlen(s);
1091
1092 switch (n) {
1093 default:
1094 break;
Ted Kremenek550025b2008-03-14 23:25:49 +00001095
Ted Kremenek02b1ff72008-03-14 21:58:42 +00001096 case 4:
Ted Kremenek550025b2008-03-14 23:25:49 +00001097 if (!memcmp(s, "exit", 4)) Builder->BuildSinks = true;
1098 break;
1099
1100 case 5:
1101 if (!memcmp(s, "panic", 5)) Builder->BuildSinks = true;
1102 break;
Ted Kremenek23271be2008-04-22 05:37:33 +00001103
1104 case 6:
Ted Kremenek0aa9a282008-05-17 00:42:01 +00001105 if (!memcmp(s, "Assert", 6)) {
1106 Builder->BuildSinks = true;
1107 break;
1108 }
Ted Kremenek6b008c62008-05-01 15:55:59 +00001109
1110 // FIXME: This is just a wrapper around throwing an exception.
1111 // Eventually inter-procedural analysis should handle this easily.
1112 if (!memcmp(s, "ziperr", 6)) Builder->BuildSinks = true;
1113
Ted Kremenek23271be2008-04-22 05:37:33 +00001114 break;
Ted Kremenekcbdc0ed2008-04-23 00:41:25 +00001115
1116 case 7:
1117 if (!memcmp(s, "assfail", 7)) Builder->BuildSinks = true;
1118 break;
Ted Kremenek0d9ff342008-04-22 06:09:33 +00001119
Ted Kremenekc37d49e2008-04-30 17:54:04 +00001120 case 8:
1121 if (!memcmp(s ,"db_error", 8)) Builder->BuildSinks = true;
1122 break;
Ted Kremenek0f84f662008-05-01 17:52:49 +00001123
1124 case 12:
1125 if (!memcmp(s, "__assert_rtn", 12)) Builder->BuildSinks = true;
1126 break;
Ted Kremenekc37d49e2008-04-30 17:54:04 +00001127
Ted Kremenek0d9ff342008-04-22 06:09:33 +00001128 case 14:
1129 if (!memcmp(s, "dtrace_assfail", 14)) Builder->BuildSinks = true;
1130 break;
Ted Kremeneka46fea72008-05-17 00:33:23 +00001131
1132 case 26:
Ted Kremenekc3888a62008-05-17 00:40:45 +00001133 if (!memcmp(s, "_XCAssertionFailureHandler", 26))
1134 Builder->BuildSinks = true;
1135
Ted Kremeneka46fea72008-05-17 00:33:23 +00001136 break;
Ted Kremenek02b1ff72008-03-14 21:58:42 +00001137 }
Ted Kremenek0d9ff342008-04-22 06:09:33 +00001138
Ted Kremenek02b1ff72008-03-14 21:58:42 +00001139 }
1140 }
Ted Kremenekb451dd32008-03-05 21:15:02 +00001141
1142 // Evaluate the call.
Ted Kremenek0a6a80b2008-04-23 20:12:28 +00001143
1144 if (isa<lval::FuncVal>(L)) {
Ted Kremenek769f3482008-03-04 22:01:56 +00001145
1146 IdentifierInfo* Info = cast<lval::FuncVal>(L).getDecl()->getIdentifier();
1147
Ted Kremenek0a6a80b2008-04-23 20:12:28 +00001148 if (unsigned id = Info->getBuiltinID())
Ted Kremenek21581c62008-03-05 22:59:42 +00001149 switch (id) {
1150 case Builtin::BI__builtin_expect: {
1151 // For __builtin_expect, just return the value of the subexpression.
1152 assert (CE->arg_begin() != CE->arg_end());
1153 RVal X = GetRVal(St, *(CE->arg_begin()));
Ted Kremenekf10f2882008-03-21 21:30:14 +00001154 MakeNode(Dst, CE, *DI, SetRVal(St, CE, X));
Ted Kremenek21581c62008-03-05 22:59:42 +00001155 continue;
1156 }
1157
1158 default:
Ted Kremenek21581c62008-03-05 22:59:42 +00001159 break;
1160 }
Ted Kremenek769f3482008-03-04 22:01:56 +00001161 }
Ted Kremenek07baa252008-02-21 18:02:17 +00001162
Ted Kremenek0a6a80b2008-04-23 20:12:28 +00001163 // Check any arguments passed-by-value against being undefined.
1164
1165 bool badArg = false;
1166
1167 for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
1168 I != E; ++I) {
1169
1170 if (GetRVal(GetState(*DI), *I).isUndef()) {
1171 NodeTy* N = Builder->generateNode(CE, GetState(*DI), *DI);
Ted Kremenekb451dd32008-03-05 21:15:02 +00001172
Ted Kremenek0a6a80b2008-04-23 20:12:28 +00001173 if (N) {
1174 N->markAsSink();
1175 UndefArgs[N] = *I;
Ted Kremenek769f3482008-03-04 22:01:56 +00001176 }
Ted Kremenek769f3482008-03-04 22:01:56 +00001177
Ted Kremenek0a6a80b2008-04-23 20:12:28 +00001178 badArg = true;
1179 break;
1180 }
Ted Kremenek769f3482008-03-04 22:01:56 +00001181 }
Ted Kremenek0a6a80b2008-04-23 20:12:28 +00001182
1183 if (badArg)
1184 continue;
1185
1186 // Dispatch to the plug-in transfer function.
1187
1188 unsigned size = Dst.size();
1189 SaveOr OldHasGen(Builder->HasGeneratedNode);
1190 EvalCall(Dst, CE, L, *DI);
1191
1192 // Handle the case where no nodes where generated. Auto-generate that
1193 // contains the updated state if we aren't generating sinks.
1194
1195 if (!Builder->BuildSinks && Dst.size() == size &&
1196 !Builder->HasGeneratedNode)
1197 MakeNode(Dst, CE, *DI, St);
Ted Kremenekd9268e32008-02-19 01:44:53 +00001198 }
1199}
1200
Ted Kremenekca5f6202008-04-15 23:06:53 +00001201//===----------------------------------------------------------------------===//
1202// Transfer function: Objective-C message expressions.
1203//===----------------------------------------------------------------------===//
1204
1205void GRExprEngine::VisitObjCMessageExpr(ObjCMessageExpr* ME, NodeTy* Pred,
1206 NodeSet& Dst){
1207
1208 VisitObjCMessageExprArgHelper(ME, ME->arg_begin(), ME->arg_end(),
1209 Pred, Dst);
1210}
1211
1212void GRExprEngine::VisitObjCMessageExprArgHelper(ObjCMessageExpr* ME,
1213 ObjCMessageExpr::arg_iterator AI,
1214 ObjCMessageExpr::arg_iterator AE,
1215 NodeTy* Pred, NodeSet& Dst) {
1216 if (AI == AE) {
1217
1218 // Process the receiver.
1219
1220 if (Expr* Receiver = ME->getReceiver()) {
1221 NodeSet Tmp;
1222 Visit(Receiver, Pred, Tmp);
1223
1224 for (NodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI)
1225 VisitObjCMessageExprDispatchHelper(ME, *NI, Dst);
1226
1227 return;
1228 }
1229
1230 VisitObjCMessageExprDispatchHelper(ME, Pred, Dst);
1231 return;
1232 }
1233
1234 NodeSet Tmp;
1235 Visit(*AI, Pred, Tmp);
1236
1237 ++AI;
1238
1239 for (NodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI)
1240 VisitObjCMessageExprArgHelper(ME, AI, AE, *NI, Dst);
1241}
1242
1243void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME,
1244 NodeTy* Pred,
1245 NodeSet& Dst) {
1246
1247 // FIXME: More logic for the processing the method call.
1248
1249 ValueState* St = GetState(Pred);
Ted Kremenek5f20a632008-05-01 18:33:28 +00001250 bool RaisesException = false;
1251
Ted Kremenekca5f6202008-04-15 23:06:53 +00001252
1253 if (Expr* Receiver = ME->getReceiver()) {
1254
1255 RVal L = GetRVal(St, Receiver);
1256
1257 // Check for undefined control-flow or calls to NULL.
1258
1259 if (L.isUndef()) {
1260 NodeTy* N = Builder->generateNode(ME, St, Pred);
1261
1262 if (N) {
1263 N->markAsSink();
1264 UndefReceivers.insert(N);
1265 }
1266
1267 return;
1268 }
Ted Kremenek5f20a632008-05-01 18:33:28 +00001269
1270 // Check if the "raise" message was sent.
1271 if (ME->getSelector() == RaiseSel)
1272 RaisesException = true;
1273 }
1274 else {
1275
1276 IdentifierInfo* ClsName = ME->getClassName();
1277 Selector S = ME->getSelector();
1278
1279 // Check for special instance methods.
1280
1281 if (!NSExceptionII) {
1282 ASTContext& Ctx = getContext();
1283
1284 NSExceptionII = &Ctx.Idents.get("NSException");
1285 }
1286
1287 if (ClsName == NSExceptionII) {
1288
1289 enum { NUM_RAISE_SELECTORS = 2 };
1290
1291 // Lazily create a cache of the selectors.
1292
1293 if (!NSExceptionInstanceRaiseSelectors) {
1294
1295 ASTContext& Ctx = getContext();
1296
1297 NSExceptionInstanceRaiseSelectors = new Selector[NUM_RAISE_SELECTORS];
1298
1299 llvm::SmallVector<IdentifierInfo*, NUM_RAISE_SELECTORS> II;
1300 unsigned idx = 0;
1301
1302 // raise:format:
Ted Kremenek2227bdf2008-05-02 17:12:56 +00001303 II.push_back(&Ctx.Idents.get("raise"));
1304 II.push_back(&Ctx.Idents.get("format"));
Ted Kremenek5f20a632008-05-01 18:33:28 +00001305 NSExceptionInstanceRaiseSelectors[idx++] =
1306 Ctx.Selectors.getSelector(II.size(), &II[0]);
1307
1308 // raise:format::arguments:
Ted Kremenek2227bdf2008-05-02 17:12:56 +00001309 II.push_back(&Ctx.Idents.get("arguments"));
Ted Kremenek5f20a632008-05-01 18:33:28 +00001310 NSExceptionInstanceRaiseSelectors[idx++] =
1311 Ctx.Selectors.getSelector(II.size(), &II[0]);
1312 }
1313
1314 for (unsigned i = 0; i < NUM_RAISE_SELECTORS; ++i)
1315 if (S == NSExceptionInstanceRaiseSelectors[i]) {
1316 RaisesException = true; break;
1317 }
1318 }
Ted Kremenekca5f6202008-04-15 23:06:53 +00001319 }
1320
1321 // Check for any arguments that are uninitialized/undefined.
1322
1323 for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end();
1324 I != E; ++I) {
1325
1326 if (GetRVal(St, *I).isUndef()) {
1327
1328 // Generate an error node for passing an uninitialized/undefined value
1329 // as an argument to a message expression. This node is a sink.
1330 NodeTy* N = Builder->generateNode(ME, St, Pred);
1331
1332 if (N) {
1333 N->markAsSink();
1334 MsgExprUndefArgs[N] = *I;
1335 }
1336
1337 return;
1338 }
Ted Kremenek5f20a632008-05-01 18:33:28 +00001339 }
1340
1341 // Check if we raise an exception. For now treat these as sinks. Eventually
1342 // we will want to handle exceptions properly.
1343
1344 SaveAndRestore<bool> OldSink(Builder->BuildSinks);
1345
1346 if (RaisesException)
1347 Builder->BuildSinks = true;
1348
Ted Kremenekca5f6202008-04-15 23:06:53 +00001349 // Dispatch to plug-in transfer function.
1350
1351 unsigned size = Dst.size();
Ted Kremenek0a6a80b2008-04-23 20:12:28 +00001352 SaveOr OldHasGen(Builder->HasGeneratedNode);
Ted Kremenek0b03c6e2008-04-18 20:35:30 +00001353
Ted Kremenekca5f6202008-04-15 23:06:53 +00001354 EvalObjCMessageExpr(Dst, ME, Pred);
1355
1356 // Handle the case where no nodes where generated. Auto-generate that
1357 // contains the updated state if we aren't generating sinks.
1358
Ted Kremenek0b03c6e2008-04-18 20:35:30 +00001359 if (!Builder->BuildSinks && Dst.size() == size && !Builder->HasGeneratedNode)
Ted Kremenekca5f6202008-04-15 23:06:53 +00001360 MakeNode(Dst, ME, Pred, St);
1361}
1362
1363//===----------------------------------------------------------------------===//
1364// Transfer functions: Miscellaneous statements.
1365//===----------------------------------------------------------------------===//
1366
Ted Kremenek07baa252008-02-21 18:02:17 +00001367void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){
Ted Kremenek54eddae2008-01-24 02:02:54 +00001368
Ted Kremenek5f585b02008-02-19 18:52:54 +00001369 NodeSet S1;
Ted Kremenek5f585b02008-02-19 18:52:54 +00001370 QualType T = CastE->getType();
1371
Ted Kremenek1d1b6c92008-03-04 22:16:08 +00001372 if (T->isReferenceType())
1373 VisitLVal(Ex, Pred, S1);
1374 else
1375 Visit(Ex, Pred, S1);
1376
Ted Kremenekfe1a0b12008-04-22 21:10:18 +00001377 // Check for casting to "void".
1378 if (T->isVoidType()) {
Ted Kremenek5f585b02008-02-19 18:52:54 +00001379
Ted Kremenek07baa252008-02-21 18:02:17 +00001380 for (NodeSet::iterator I1 = S1.begin(), E1 = S1.end(); I1 != E1; ++I1)
Ted Kremenek5f585b02008-02-19 18:52:54 +00001381 Dst.Add(*I1);
1382
Ted Kremenek54eddae2008-01-24 02:02:54 +00001383 return;
1384 }
1385
Ted Kremenekfe1a0b12008-04-22 21:10:18 +00001386 // FIXME: The rest of this should probably just go into EvalCall, and
1387 // let the transfer function object be responsible for constructing
1388 // nodes.
1389
1390 QualType ExTy = Ex->getType();
1391
Ted Kremenek07baa252008-02-21 18:02:17 +00001392 for (NodeSet::iterator I1 = S1.begin(), E1 = S1.end(); I1 != E1; ++I1) {
Ted Kremenek54eddae2008-01-24 02:02:54 +00001393 NodeTy* N = *I1;
Ted Kremenek50ef5ff2008-03-10 04:11:42 +00001394 ValueState* St = GetState(N);
Ted Kremenek5f6b4422008-04-29 21:04:26 +00001395 RVal V = GetRVal(St, Ex);
Ted Kremenekfe1a0b12008-04-22 21:10:18 +00001396
1397 // Unknown?
1398
1399 if (V.isUnknown()) {
1400 Dst.Add(N);
1401 continue;
1402 }
1403
1404 // Undefined?
1405
1406 if (V.isUndef()) {
1407 MakeNode(Dst, CastE, N, SetRVal(St, CastE, V));
1408 continue;
1409 }
1410
1411 // Check for casts from pointers to integers.
Ted Kremenek9e2c1ea2008-05-09 23:45:33 +00001412 if (T->isIntegerType() && LVal::IsLValType(ExTy)) {
Ted Kremenekfe1a0b12008-04-22 21:10:18 +00001413 unsigned bits = getContext().getTypeSize(ExTy);
1414
1415 // FIXME: Determine if the number of bits of the target type is
1416 // equal or exceeds the number of bits to store the pointer value.
1417 // If not, flag an error.
1418
1419 V = nonlval::LValAsInteger::Make(BasicVals, cast<LVal>(V), bits);
1420 MakeNode(Dst, CastE, N, SetRVal(St, CastE, V));
1421 continue;
1422 }
1423
1424 // Check for casts from integers to pointers.
Ted Kremenek9e2c1ea2008-05-09 23:45:33 +00001425 if (LVal::IsLValType(T) && ExTy->isIntegerType())
Ted Kremenekfe1a0b12008-04-22 21:10:18 +00001426 if (nonlval::LValAsInteger *LV = dyn_cast<nonlval::LValAsInteger>(&V)) {
1427 // Just unpackage the lval and return it.
1428 V = LV->getLVal();
1429 MakeNode(Dst, CastE, N, SetRVal(St, CastE, V));
1430 continue;
1431 }
1432
1433 // All other cases.
Ted Kremenek1d1b6c92008-03-04 22:16:08 +00001434
Ted Kremenekf10f2882008-03-21 21:30:14 +00001435 MakeNode(Dst, CastE, N, SetRVal(St, CastE, EvalCast(V, CastE->getType())));
Ted Kremenek54eddae2008-01-24 02:02:54 +00001436 }
Ted Kremenekb9c30e32008-01-24 20:55:43 +00001437}
1438
Ted Kremenekcfbc56a2008-04-22 22:25:27 +00001439void GRExprEngine::VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst) {
1440 VisitDeclStmtAux(DS, DS->getDecl(), Pred, Dst);
1441}
1442
1443void GRExprEngine::VisitDeclStmtAux(DeclStmt* DS, ScopedDecl* D,
1444 NodeTy* Pred, NodeSet& Dst) {
1445
1446 if (!D)
1447 return;
Ted Kremenekb9c30e32008-01-24 20:55:43 +00001448
Ted Kremenekcfbc56a2008-04-22 22:25:27 +00001449 if (!isa<VarDecl>(D)) {
1450 VisitDeclStmtAux(DS, D->getNextDeclarator(), Pred, Dst);
1451 return;
1452 }
Ted Kremenekb9c30e32008-01-24 20:55:43 +00001453
Ted Kremenekcfbc56a2008-04-22 22:25:27 +00001454 const VarDecl* VD = dyn_cast<VarDecl>(D);
1455
1456 // FIXME: Add support for local arrays.
1457 if (VD->getType()->isArrayType()) {
1458 VisitDeclStmtAux(DS, D->getNextDeclarator(), Pred, Dst);
1459 return;
1460 }
1461
1462 Expr* Ex = const_cast<Expr*>(VD->getInit());
1463
1464 // FIXME: static variables may have an initializer, but the second
1465 // time a function is called those values may not be current.
1466 NodeSet Tmp;
1467
1468 if (Ex) Visit(Ex, Pred, Tmp);
1469 if (Tmp.empty()) Tmp.Add(Pred);
1470
1471 for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
Ted Kremeneke0258002008-02-19 00:29:51 +00001472
Ted Kremenekcfbc56a2008-04-22 22:25:27 +00001473 ValueState* St = GetState(*I);
1474
1475 if (!Ex && VD->hasGlobalStorage()) {
Ted Kremeneke0258002008-02-19 00:29:51 +00001476
Ted Kremenekcfbc56a2008-04-22 22:25:27 +00001477 // Handle variables with global storage and no initializers.
Ted Kremenek07baa252008-02-21 18:02:17 +00001478
Ted Kremenekcfbc56a2008-04-22 22:25:27 +00001479 // FIXME: static variables may have an initializer, but the second
1480 // time a function is called those values may not be current.
1481
1482
1483 // In this context, Static => Local variable.
1484
1485 assert (!VD->getStorageClass() == VarDecl::Static ||
1486 !VD->isFileVarDecl());
1487
1488 // If there is no initializer, set the value of the
1489 // variable to "Undefined".
1490
1491 if (VD->getStorageClass() == VarDecl::Static) {
1492
1493 // C99: 6.7.8 Initialization
1494 // If an object that has static storage duration is not initialized
1495 // explicitly, then:
1496 // —if it has pointer type, it is initialized to a null pointer;
1497 // —if it has arithmetic type, it is initialized to (positive or
1498 // unsigned) zero;
Ted Kremenek04ab4c12008-02-27 19:21:33 +00001499
Ted Kremenekcfbc56a2008-04-22 22:25:27 +00001500 // FIXME: Handle structs. Now we treat their values as unknown.
Ted Kremenek98d093b2008-03-04 20:40:11 +00001501
1502 QualType T = VD->getType();
Ted Kremenek04ab4c12008-02-27 19:21:33 +00001503
Ted Kremenek9e2c1ea2008-05-09 23:45:33 +00001504 if (LVal::IsLValType(T))
Ted Kremenekcfbc56a2008-04-22 22:25:27 +00001505 St = SetRVal(St, lval::DeclVal(VD),
1506 lval::ConcreteInt(BasicVals.getValue(0, T)));
1507 else if (T->isIntegerType())
1508 St = SetRVal(St, lval::DeclVal(VD),
1509 nonlval::ConcreteInt(BasicVals.getValue(0, T)));
Ted Kremeneka6cfcc92008-03-04 04:18:04 +00001510
Ted Kremenekcfbc56a2008-04-22 22:25:27 +00001511 // FIXME: Handle structs. Now we treat them as unknown. What
1512 // we need to do is treat their members as unknown.
Ted Kremenek04ab4c12008-02-27 19:21:33 +00001513 }
Ted Kremenek8c9bc342008-01-28 22:51:57 +00001514 }
Ted Kremenekcfbc56a2008-04-22 22:25:27 +00001515 else {
1516
1517 // FIXME: Handle structs. Now we treat them as unknown. What
1518 // we need to do is treat their members as unknown.
Ted Kremenekb9c30e32008-01-24 20:55:43 +00001519
Ted Kremenekcfbc56a2008-04-22 22:25:27 +00001520 QualType T = VD->getType();
1521
Ted Kremenek9e2c1ea2008-05-09 23:45:33 +00001522 if (LVal::IsLValType(T) || T->isIntegerType()) {
Ted Kremenekc37d49e2008-04-30 17:54:04 +00001523
1524 RVal V = Ex ? GetRVal(St, Ex) : UndefinedVal();
1525
1526 if (Ex && V.isUnknown()) {
1527
1528 // EXPERIMENTAL: "Conjured" symbols.
1529
1530 unsigned Count = Builder->getCurrentBlockCount();
1531 SymbolID Sym = SymMgr.getConjuredSymbol(Ex, Count);
1532
Ted Kremenek9e2c1ea2008-05-09 23:45:33 +00001533 V = LVal::IsLValType(Ex->getType())
Ted Kremenekc37d49e2008-04-30 17:54:04 +00001534 ? cast<RVal>(lval::SymbolVal(Sym))
1535 : cast<RVal>(nonlval::SymbolVal(Sym));
1536 }
1537
1538 St = SetRVal(St, lval::DeclVal(VD), V);
1539 }
Ted Kremenekcfbc56a2008-04-22 22:25:27 +00001540 }
1541
1542 // Create a new node. We don't really need to create a new NodeSet
1543 // here, but it simplifies things and doesn't cost much.
1544 NodeSet Tmp2;
1545 MakeNode(Tmp2, DS, *I, St);
1546 if (Tmp2.empty()) Tmp2.Add(*I);
1547
1548 for (NodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end(); I2!=E2; ++I2)
1549 VisitDeclStmtAux(DS, D->getNextDeclarator(), *I2, Dst);
1550 }
Ted Kremenekb9c30e32008-01-24 20:55:43 +00001551}
Ted Kremenek54eddae2008-01-24 02:02:54 +00001552
Ted Kremenek1f0eb992008-02-05 00:26:40 +00001553
Ted Kremenekfd85f292008-02-12 19:49:57 +00001554/// VisitSizeOfAlignOfTypeExpr - Transfer function for sizeof(type).
Ted Kremenek07baa252008-02-21 18:02:17 +00001555void GRExprEngine::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr* Ex,
1556 NodeTy* Pred,
1557 NodeSet& Dst) {
Ted Kremenek07baa252008-02-21 18:02:17 +00001558 QualType T = Ex->getArgumentType();
Ted Kremenekc3b12832008-03-15 03:13:20 +00001559 uint64_t amt;
1560
1561 if (Ex->isSizeOf()) {
Ted Kremenek9cfda3f2008-02-21 18:43:30 +00001562
Ted Kremenekc3b12832008-03-15 03:13:20 +00001563 // FIXME: Add support for VLAs.
1564 if (!T.getTypePtr()->isConstantSizeType())
1565 return;
1566
Ted Kremeneka9223262008-04-30 21:31:12 +00001567 // Some code tries to take the sizeof an ObjCInterfaceType, relying that
1568 // the compiler has laid out its representation. Just report Unknown
1569 // for these.
1570 if (T->isObjCInterfaceType())
1571 return;
1572
Ted Kremenekc3b12832008-03-15 03:13:20 +00001573 amt = 1; // Handle sizeof(void)
1574
1575 if (T != getContext().VoidTy)
1576 amt = getContext().getTypeSize(T) / 8;
1577
1578 }
1579 else // Get alignment of the type.
Ted Kremenek8eac9c02008-03-15 03:13:55 +00001580 amt = getContext().getTypeAlign(T) / 8;
Ted Kremenekfd85f292008-02-12 19:49:57 +00001581
Ted Kremenekf10f2882008-03-21 21:30:14 +00001582 MakeNode(Dst, Ex, Pred,
Ted Kremenek5f6b4422008-04-29 21:04:26 +00001583 SetRVal(GetState(Pred), Ex,
1584 NonLVal::MakeVal(BasicVals, amt, Ex->getType())));
Ted Kremenekfd85f292008-02-12 19:49:57 +00001585}
1586
Ted Kremenekb996ebc2008-02-20 04:02:35 +00001587
Ted Kremenek07baa252008-02-21 18:02:17 +00001588void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
Ted Kremenek5f6b4422008-04-29 21:04:26 +00001589 NodeSet& Dst, bool asLVal) {
1590
Ted Kremenekb996ebc2008-02-20 04:02:35 +00001591 switch (U->getOpcode()) {
Ted Kremenekb996ebc2008-02-20 04:02:35 +00001592
1593 default:
Ted Kremenekb996ebc2008-02-20 04:02:35 +00001594 break;
Ted Kremenekfe952cb2008-06-19 17:55:38 +00001595
Ted Kremenek5f6b4422008-04-29 21:04:26 +00001596 case UnaryOperator::Deref: {
1597
1598 Expr* Ex = U->getSubExpr()->IgnoreParens();
1599 NodeSet Tmp;
1600 Visit(Ex, Pred, Tmp);
1601
1602 for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
Ted Kremenek07baa252008-02-21 18:02:17 +00001603
Ted Kremenek5f6b4422008-04-29 21:04:26 +00001604 ValueState* St = GetState(*I);
1605 RVal location = GetRVal(St, Ex);
1606
1607 if (asLVal)
1608 MakeNode(Dst, U, *I, SetRVal(St, U, location));
1609 else
Ted Kremenekbb9bd732008-05-21 15:48:33 +00001610 EvalLoad(Dst, U, *I, St, location);
Ted Kremenek5f6b4422008-04-29 21:04:26 +00001611 }
1612
1613 return;
Ted Kremenek07baa252008-02-21 18:02:17 +00001614 }
Ted Kremenek5c4d4092008-04-30 21:45:55 +00001615
Ted Kremenekfe952cb2008-06-19 17:55:38 +00001616 case UnaryOperator::Real: {
1617
1618 Expr* Ex = U->getSubExpr()->IgnoreParens();
1619 NodeSet Tmp;
1620 Visit(Ex, Pred, Tmp);
1621
1622 for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
1623
1624 // FIXME: We don't have complex RValues yet.
1625 if (Ex->getType()->isAnyComplexType()) {
1626 // Just report "Unknown."
1627 Dst.Add(*I);
1628 continue;
1629 }
1630
1631 // For all other types, UnaryOperator::Real is an identity operation.
1632 assert (U->getType() == Ex->getType());
1633 ValueState* St = GetState(*I);
1634 MakeNode(Dst, U, *I, SetRVal(St, U, GetRVal(St, Ex)));
1635 }
1636
1637 return;
1638 }
1639
1640 case UnaryOperator::Imag: {
1641
1642 Expr* Ex = U->getSubExpr()->IgnoreParens();
1643 NodeSet Tmp;
1644 Visit(Ex, Pred, Tmp);
1645
1646 for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
1647 // FIXME: We don't have complex RValues yet.
1648 if (Ex->getType()->isAnyComplexType()) {
1649 // Just report "Unknown."
1650 Dst.Add(*I);
1651 continue;
1652 }
1653
1654 // For all other types, UnaryOperator::Float returns 0.
1655 assert (Ex->getType()->isIntegerType());
1656 ValueState* St = GetState(*I);
1657 RVal X = NonLVal::MakeVal(BasicVals, 0, Ex->getType());
1658 MakeNode(Dst, U, *I, SetRVal(St, U, X));
1659 }
1660
1661 return;
1662 }
1663
1664 // FIXME: Just report "Unknown" for OffsetOf.
Ted Kremenek5c4d4092008-04-30 21:45:55 +00001665 case UnaryOperator::OffsetOf:
Ted Kremenek5c4d4092008-04-30 21:45:55 +00001666 Dst.Add(Pred);
1667 return;
1668
Ted Kremenek5f6b4422008-04-29 21:04:26 +00001669 case UnaryOperator::Plus: assert (!asLVal); // FALL-THROUGH.
1670 case UnaryOperator::Extension: {
1671
1672 // Unary "+" is a no-op, similar to a parentheses. We still have places
1673 // where it may be a block-level expression, so we need to
1674 // generate an extra node that just propagates the value of the
1675 // subexpression.
1676
1677 Expr* Ex = U->getSubExpr()->IgnoreParens();
1678 NodeSet Tmp;
1679 Visit(Ex, Pred, Tmp);
1680
1681 for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
1682 ValueState* St = GetState(*I);
1683 MakeNode(Dst, U, *I, SetRVal(St, U, GetRVal(St, Ex)));
1684 }
1685
1686 return;
Ted Kremenek07baa252008-02-21 18:02:17 +00001687 }
Ted Kremenek1be5eb92008-01-24 02:28:56 +00001688
Ted Kremenek5f6b4422008-04-29 21:04:26 +00001689 case UnaryOperator::AddrOf: {
Ted Kremenekb996ebc2008-02-20 04:02:35 +00001690
Ted Kremenek5f6b4422008-04-29 21:04:26 +00001691 assert (!asLVal);
1692 Expr* Ex = U->getSubExpr()->IgnoreParens();
1693 NodeSet Tmp;
1694 VisitLVal(Ex, Pred, Tmp);
1695
1696 for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
1697 ValueState* St = GetState(*I);
1698 RVal V = GetRVal(St, Ex);
1699 St = SetRVal(St, U, V);
1700 MakeNode(Dst, U, *I, St);
Ted Kremenekb8782e12008-02-21 19:15:37 +00001701 }
Ted Kremenek07baa252008-02-21 18:02:17 +00001702
Ted Kremenek5f6b4422008-04-29 21:04:26 +00001703 return;
1704 }
1705
1706 case UnaryOperator::LNot:
1707 case UnaryOperator::Minus:
1708 case UnaryOperator::Not: {
1709
1710 assert (!asLVal);
1711 Expr* Ex = U->getSubExpr()->IgnoreParens();
1712 NodeSet Tmp;
1713 Visit(Ex, Pred, Tmp);
1714
1715 for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
1716 ValueState* St = GetState(*I);
1717 RVal V = GetRVal(St, Ex);
1718
1719 if (V.isUnknownOrUndef()) {
1720 MakeNode(Dst, U, *I, SetRVal(St, U, V));
1721 continue;
1722 }
1723
1724 switch (U->getOpcode()) {
1725 default:
1726 assert(false && "Invalid Opcode.");
1727 break;
1728
1729 case UnaryOperator::Not:
1730 St = SetRVal(St, U, EvalComplement(cast<NonLVal>(V)));
1731 break;
1732
1733 case UnaryOperator::Minus:
1734 St = SetRVal(St, U, EvalMinus(U, cast<NonLVal>(V)));
1735 break;
1736
1737 case UnaryOperator::LNot:
1738
1739 // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
1740 //
1741 // Note: technically we do "E == 0", but this is the same in the
1742 // transfer functions as "0 == E".
1743
1744 if (isa<LVal>(V)) {
1745 lval::ConcreteInt X(BasicVals.getZeroWithPtrWidth());
1746 RVal Result = EvalBinOp(BinaryOperator::EQ, cast<LVal>(V), X);
1747 St = SetRVal(St, U, Result);
1748 }
1749 else {
1750 nonlval::ConcreteInt X(BasicVals.getValue(0, Ex->getType()));
1751 RVal Result = EvalBinOp(BinaryOperator::EQ, cast<NonLVal>(V), X);
1752 St = SetRVal(St, U, Result);
1753 }
1754
1755 break;
1756 }
1757
1758 MakeNode(Dst, U, *I, St);
1759 }
1760
1761 return;
1762 }
1763
1764 case UnaryOperator::SizeOf: {
1765
1766 QualType T = U->getSubExpr()->getType();
1767
1768 // FIXME: Add support for VLAs.
1769
1770 if (!T.getTypePtr()->isConstantSizeType())
1771 return;
1772
1773 uint64_t size = getContext().getTypeSize(T) / 8;
1774 ValueState* St = GetState(Pred);
1775 St = SetRVal(St, U, NonLVal::MakeVal(BasicVals, size, U->getType()));
1776
1777 MakeNode(Dst, U, Pred, St);
1778 return;
1779 }
1780 }
1781
1782 // Handle ++ and -- (both pre- and post-increment).
1783
1784 assert (U->isIncrementDecrementOp());
1785 NodeSet Tmp;
1786 Expr* Ex = U->getSubExpr()->IgnoreParens();
1787 VisitLVal(Ex, Pred, Tmp);
1788
1789 for (NodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) {
1790
1791 ValueState* St = GetState(*I);
1792 RVal V1 = GetRVal(St, Ex);
1793
1794 // Perform a load.
1795 NodeSet Tmp2;
1796 EvalLoad(Tmp2, Ex, *I, St, V1);
1797
1798 for (NodeSet::iterator I2 = Tmp2.begin(), E2 = Tmp2.end(); I2!=E2; ++I2) {
1799
1800 St = GetState(*I2);
1801 RVal V2 = GetRVal(St, Ex);
1802
1803 // Propagate unknown and undefined values.
1804 if (V2.isUnknownOrUndef()) {
1805 MakeNode(Dst, U, *I2, SetRVal(St, U, V2));
Ted Kremenek07baa252008-02-21 18:02:17 +00001806 continue;
1807 }
1808
Ted Kremenekb1669d42008-02-21 19:29:23 +00001809 // Handle all other values.
Ted Kremenek22640ce2008-02-15 22:09:30 +00001810
1811 BinaryOperator::Opcode Op = U->isIncrementOp() ? BinaryOperator::Add
1812 : BinaryOperator::Sub;
1813
Ted Kremenek5f6b4422008-04-29 21:04:26 +00001814 RVal Result = EvalBinOp(Op, V2, MakeConstantVal(1U, U));
1815 St = SetRVal(St, U, U->isPostfix() ? V2 : Result);
Ted Kremenek15cb0782008-02-06 22:50:25 +00001816
Ted Kremenek5f6b4422008-04-29 21:04:26 +00001817 // Perform the store.
Ted Kremenekbf573852008-04-30 04:23:07 +00001818 EvalStore(Dst, U, *I2, St, V1, Result);
Ted Kremeneke1f38b62008-02-07 01:08:27 +00001819 }
Ted Kremenekd0d86202008-04-21 23:43:38 +00001820 }
Ted Kremeneke1f38b62008-02-07 01:08:27 +00001821}
1822
Ted Kremenek31803c32008-03-17 21:11:24 +00001823void GRExprEngine::VisitAsmStmt(AsmStmt* A, NodeTy* Pred, NodeSet& Dst) {
1824 VisitAsmStmtHelperOutputs(A, A->begin_outputs(), A->end_outputs(), Pred, Dst);
1825}
1826
1827void GRExprEngine::VisitAsmStmtHelperOutputs(AsmStmt* A,
1828 AsmStmt::outputs_iterator I,
1829 AsmStmt::outputs_iterator E,
1830 NodeTy* Pred, NodeSet& Dst) {
1831 if (I == E) {
1832 VisitAsmStmtHelperInputs(A, A->begin_inputs(), A->end_inputs(), Pred, Dst);
1833 return;
1834 }
1835
1836 NodeSet Tmp;
1837 VisitLVal(*I, Pred, Tmp);
1838
1839 ++I;
1840
1841 for (NodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI)
1842 VisitAsmStmtHelperOutputs(A, I, E, *NI, Dst);
1843}
1844
1845void GRExprEngine::VisitAsmStmtHelperInputs(AsmStmt* A,
1846 AsmStmt::inputs_iterator I,
1847 AsmStmt::inputs_iterator E,
1848 NodeTy* Pred, NodeSet& Dst) {
1849 if (I == E) {
1850
1851 // We have processed both the inputs and the outputs. All of the outputs
1852 // should evaluate to LVals. Nuke all of their values.
1853
1854 // FIXME: Some day in the future it would be nice to allow a "plug-in"
1855 // which interprets the inline asm and stores proper results in the
1856 // outputs.
1857
1858 ValueState* St = GetState(Pred);
1859
1860 for (AsmStmt::outputs_iterator OI = A->begin_outputs(),
1861 OE = A->end_outputs(); OI != OE; ++OI) {
1862
Ted Kremenek5f6b4422008-04-29 21:04:26 +00001863 RVal X = GetRVal(St, *OI);
1864 assert (!isa<NonLVal>(X)); // Should be an Lval, or unknown, undef.
Ted Kremenek31803c32008-03-17 21:11:24 +00001865
1866 if (isa<LVal>(X))
1867 St = SetRVal(St, cast<LVal>(X), UnknownVal());
1868 }
1869
Ted Kremenekf10f2882008-03-21 21:30:14 +00001870 MakeNode(Dst, A, Pred, St);
Ted Kremenek31803c32008-03-17 21:11:24 +00001871 return;
1872 }
1873
1874 NodeSet Tmp;
1875 Visit(*I, Pred, Tmp);
1876
1877 ++I;
1878
1879 for (NodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI)
1880 VisitAsmStmtHelperInputs(A, I, E, *NI, Dst);
1881}
1882
Ted Kremenekc208f4e2008-04-16 23:05:51 +00001883void GRExprEngine::EvalReturn(NodeSet& Dst, ReturnStmt* S, NodeTy* Pred) {
1884 assert (Builder && "GRStmtNodeBuilder must be defined.");
1885
1886 unsigned size = Dst.size();
Ted Kremenek0b03c6e2008-04-18 20:35:30 +00001887
Ted Kremenek0a6a80b2008-04-23 20:12:28 +00001888 SaveAndRestore<bool> OldSink(Builder->BuildSinks);
1889 SaveOr OldHasGen(Builder->HasGeneratedNode);
Ted Kremenek0b03c6e2008-04-18 20:35:30 +00001890
Ted Kremenekc208f4e2008-04-16 23:05:51 +00001891 TF->EvalReturn(Dst, *this, *Builder, S, Pred);
1892
Ted Kremenek0b03c6e2008-04-18 20:35:30 +00001893 // Handle the case where no nodes where generated.
Ted Kremenekc208f4e2008-04-16 23:05:51 +00001894
Ted Kremenek0b03c6e2008-04-18 20:35:30 +00001895 if (!Builder->BuildSinks && Dst.size() == size && !Builder->HasGeneratedNode)
Ted Kremenekc208f4e2008-04-16 23:05:51 +00001896 MakeNode(Dst, S, Pred, GetState(Pred));
1897}
1898
Ted Kremenek108048c2008-03-31 15:02:58 +00001899void GRExprEngine::VisitReturnStmt(ReturnStmt* S, NodeTy* Pred, NodeSet& Dst) {
1900
1901 Expr* R = S->getRetValue();
1902
1903 if (!R) {
Ted Kremenekc208f4e2008-04-16 23:05:51 +00001904 EvalReturn(Dst, S, Pred);
Ted Kremenek108048c2008-03-31 15:02:58 +00001905 return;
1906 }
Ted Kremenekc208f4e2008-04-16 23:05:51 +00001907
1908 NodeSet DstRet;
Ted Kremenek108048c2008-03-31 15:02:58 +00001909 QualType T = R->getType();
1910
Chris Lattnera05f7d22008-04-02 17:45:06 +00001911 if (T->isPointerLikeType()) {
Ted Kremenek108048c2008-03-31 15:02:58 +00001912
1913 // Check if any of the return values return the address of a stack variable.
1914
1915 NodeSet Tmp;
1916 Visit(R, Pred, Tmp);
1917
1918 for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
1919 RVal X = GetRVal((*I)->getState(), R);
1920
1921 if (isa<lval::DeclVal>(X)) {
1922
1923 if (cast<lval::DeclVal>(X).getDecl()->hasLocalStorage()) {
1924
1925 // Create a special node representing the v
1926
1927 NodeTy* RetStackNode = Builder->generateNode(S, GetState(*I), *I);
1928
1929 if (RetStackNode) {
1930 RetStackNode->markAsSink();
1931 RetsStackAddr.insert(RetStackNode);
1932 }
1933
1934 continue;
1935 }
1936 }
1937
Ted Kremenekc208f4e2008-04-16 23:05:51 +00001938 DstRet.Add(*I);
Ted Kremenek108048c2008-03-31 15:02:58 +00001939 }
1940 }
1941 else
Ted Kremenekc208f4e2008-04-16 23:05:51 +00001942 Visit(R, Pred, DstRet);
1943
1944 for (NodeSet::iterator I=DstRet.begin(), E=DstRet.end(); I!=E; ++I)
1945 EvalReturn(Dst, S, *I);
Ted Kremenek108048c2008-03-31 15:02:58 +00001946}
Ted Kremenekc6b7a1e2008-03-25 00:34:37 +00001947
Ted Kremenekca5f6202008-04-15 23:06:53 +00001948//===----------------------------------------------------------------------===//
1949// Transfer functions: Binary operators.
1950//===----------------------------------------------------------------------===//
1951
Ted Kremenek5f6b4422008-04-29 21:04:26 +00001952bool GRExprEngine::CheckDivideZero(Expr* Ex, ValueState* St,
1953 NodeTy* Pred, RVal Denom) {
1954
1955 // Divide by undefined? (potentially zero)
1956
1957 if (Denom.isUndef()) {
1958 NodeTy* DivUndef = Builder->generateNode(Ex, St, Pred);
1959
1960 if (DivUndef) {
1961 DivUndef->markAsSink();
1962 ExplicitBadDivides.insert(DivUndef);
1963 }
1964
1965 return true;
1966 }
1967
1968 // Check for divide/remainder-by-zero.
1969 // First, "assume" that the denominator is 0 or undefined.
1970
1971 bool isFeasibleZero = false;
1972 ValueState* ZeroSt = Assume(St, Denom, false, isFeasibleZero);
1973
1974 // Second, "assume" that the denominator cannot be 0.
1975
1976 bool isFeasibleNotZero = false;
1977 St = Assume(St, Denom, true, isFeasibleNotZero);
1978
1979 // Create the node for the divide-by-zero (if it occurred).
1980
1981 if (isFeasibleZero)
1982 if (NodeTy* DivZeroNode = Builder->generateNode(Ex, ZeroSt, Pred)) {
1983 DivZeroNode->markAsSink();
1984
1985 if (isFeasibleNotZero)
1986 ImplicitBadDivides.insert(DivZeroNode);
1987 else
1988 ExplicitBadDivides.insert(DivZeroNode);
1989
1990 }
1991
1992 return !isFeasibleNotZero;
1993}
1994
Ted Kremenek30fa28b2008-02-13 17:41:41 +00001995void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
Ted Kremenekaee121c2008-02-13 23:08:21 +00001996 GRExprEngine::NodeTy* Pred,
1997 GRExprEngine::NodeSet& Dst) {
Ted Kremenek5f6b4422008-04-29 21:04:26 +00001998
1999 NodeSet Tmp1;
2000 Expr* LHS = B->getLHS()->IgnoreParens();
2001 Expr* RHS = B->getRHS()->IgnoreParens();
Ted Kremeneke1f38b62008-02-07 01:08:27 +00002002
2003 if (B->isAssignmentOp())
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002004 VisitLVal(LHS, Pred, Tmp1);
Ted Kremeneke1f38b62008-02-07 01:08:27 +00002005 else
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002006 Visit(LHS, Pred, Tmp1);
Ted Kremenekafba4b22008-01-16 00:53:15 +00002007
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002008 for (NodeSet::iterator I1=Tmp1.begin(), E1=Tmp1.end(); I1 != E1; ++I1) {
Ted Kremenek07baa252008-02-21 18:02:17 +00002009
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002010 RVal LeftV = GetRVal((*I1)->getState(), LHS);
Ted Kremeneke860db82008-01-17 00:52:48 +00002011
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002012 // Process the RHS.
2013
2014 NodeSet Tmp2;
2015 Visit(RHS, *I1, Tmp2);
2016
2017 // With both the LHS and RHS evaluated, process the operation itself.
2018
2019 for (NodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end(); I2 != E2; ++I2) {
Ted Kremenek07baa252008-02-21 18:02:17 +00002020
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002021 ValueState* St = GetState(*I2);
Ted Kremenek2c369792008-02-25 18:42:54 +00002022 RVal RightV = GetRVal(St, RHS);
Ted Kremenek15cb0782008-02-06 22:50:25 +00002023 BinaryOperator::Opcode Op = B->getOpcode();
2024
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002025 switch (Op) {
Ted Kremenek07baa252008-02-21 18:02:17 +00002026
Ted Kremenekf031b872008-01-23 19:59:44 +00002027 case BinaryOperator::Assign: {
Ted Kremenek07baa252008-02-21 18:02:17 +00002028
Ted Kremenekd4676512008-03-12 21:45:47 +00002029 // EXPERIMENTAL: "Conjured" symbols.
2030
2031 if (RightV.isUnknown()) {
2032 unsigned Count = Builder->getCurrentBlockCount();
2033 SymbolID Sym = SymMgr.getConjuredSymbol(B->getRHS(), Count);
2034
Ted Kremenek9e2c1ea2008-05-09 23:45:33 +00002035 RightV = LVal::IsLValType(B->getRHS()->getType())
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002036 ? cast<RVal>(lval::SymbolVal(Sym))
2037 : cast<RVal>(nonlval::SymbolVal(Sym));
Ted Kremenekd4676512008-03-12 21:45:47 +00002038 }
2039
Ted Kremenekd4676512008-03-12 21:45:47 +00002040 // Simulate the effects of a "store": bind the value of the RHS
2041 // to the L-Value represented by the LHS.
Ted Kremenekf5069582008-04-16 18:21:25 +00002042
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002043 EvalStore(Dst, B, *I2, SetRVal(St, B, RightV), LeftV, RightV);
Ted Kremenekf5069582008-04-16 18:21:25 +00002044 continue;
Ted Kremenekf031b872008-01-23 19:59:44 +00002045 }
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002046
2047 case BinaryOperator::Div:
2048 case BinaryOperator::Rem:
2049
2050 // Special checking for integer denominators.
2051
2052 if (RHS->getType()->isIntegerType()
2053 && CheckDivideZero(B, St, *I2, RightV))
2054 continue;
2055
2056 // FALL-THROUGH.
Ted Kremenekf031b872008-01-23 19:59:44 +00002057
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002058 default: {
2059
2060 if (B->isAssignmentOp())
Ted Kremenek07baa252008-02-21 18:02:17 +00002061 break;
Ted Kremenek07baa252008-02-21 18:02:17 +00002062
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002063 // Process non-assignements except commas or short-circuited
2064 // logical expressions (LAnd and LOr).
Ted Kremenek07baa252008-02-21 18:02:17 +00002065
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002066 RVal Result = EvalBinOp(Op, LeftV, RightV);
2067
2068 if (Result.isUnknown()) {
2069 Dst.Add(*I2);
Ted Kremenekb8782e12008-02-21 19:15:37 +00002070 continue;
2071 }
Ted Kremenek07baa252008-02-21 18:02:17 +00002072
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002073 if (Result.isUndef() && !LeftV.isUndef() && !RightV.isUndef()) {
Ted Kremenek07baa252008-02-21 18:02:17 +00002074
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002075 // The operands were *not* undefined, but the result is undefined.
2076 // This is a special node that should be flagged as an error.
Ted Kremenek2c369792008-02-25 18:42:54 +00002077
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002078 if (NodeTy* UndefNode = Builder->generateNode(B, St, *I2)) {
Ted Kremenekc2d07202008-02-28 20:32:03 +00002079 UndefNode->markAsSink();
2080 UndefResults.insert(UndefNode);
2081 }
2082
2083 continue;
2084 }
2085
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002086 // Otherwise, create a new node.
2087
2088 MakeNode(Dst, B, *I2, SetRVal(St, B, Result));
Ted Kremenekf5069582008-04-16 18:21:25 +00002089 continue;
Ted Kremenek15cb0782008-02-06 22:50:25 +00002090 }
Ted Kremenekf031b872008-01-23 19:59:44 +00002091 }
Ted Kremenek07baa252008-02-21 18:02:17 +00002092
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002093 assert (B->isCompoundAssignmentOp());
2094
2095 if (Op >= BinaryOperator::AndAssign)
2096 ((int&) Op) -= (BinaryOperator::AndAssign - BinaryOperator::And);
2097 else
2098 ((int&) Op) -= BinaryOperator::MulAssign;
2099
2100 // Perform a load (the LHS). This performs the checks for
2101 // null dereferences, and so on.
2102 NodeSet Tmp3;
2103 RVal location = GetRVal(St, LHS);
2104 EvalLoad(Tmp3, LHS, *I2, St, location);
2105
2106 for (NodeSet::iterator I3=Tmp3.begin(), E3=Tmp3.end(); I3!=E3; ++I3) {
2107
2108 St = GetState(*I3);
2109 RVal V = GetRVal(St, LHS);
2110
2111 // Propagate undefined values (left-side).
2112 if (V.isUndef()) {
2113 EvalStore(Dst, B, *I3, SetRVal(St, B, V), location, V);
2114 continue;
2115 }
2116
2117 // Propagate unknown values (left and right-side).
2118 if (RightV.isUnknown() || V.isUnknown()) {
2119 EvalStore(Dst, B, *I3, SetRVal(St, B, UnknownVal()), location,
2120 UnknownVal());
2121 continue;
2122 }
2123
2124 // At this point:
2125 //
2126 // The LHS is not Undef/Unknown.
2127 // The RHS is not Unknown.
2128
2129 // Get the computation type.
2130 QualType CTy = cast<CompoundAssignOperator>(B)->getComputationType();
2131
2132 // Perform promotions.
2133 V = EvalCast(V, CTy);
2134 RightV = EvalCast(RightV, CTy);
2135
2136 // Evaluate operands and promote to result type.
2137
2138 if ((Op == BinaryOperator::Div || Op == BinaryOperator::Rem)
2139 && RHS->getType()->isIntegerType()) {
2140
2141 if (CheckDivideZero(B, St, *I3, RightV))
2142 continue;
2143 }
2144 else if (RightV.isUndef()) {
2145
2146 // Propagate undefined values (right-side).
2147
2148 EvalStore(Dst, B, *I3, SetRVal(St, B, RightV), location, RightV);
2149 continue;
2150 }
2151
2152 // Compute the result of the operation.
2153
2154 RVal Result = EvalCast(EvalBinOp(Op, V, RightV), B->getType());
2155
2156 if (Result.isUndef()) {
2157
2158 // The operands were not undefined, but the result is undefined.
2159
2160 if (NodeTy* UndefNode = Builder->generateNode(B, St, *I3)) {
2161 UndefNode->markAsSink();
2162 UndefResults.insert(UndefNode);
2163 }
2164
2165 continue;
2166 }
2167
2168 EvalStore(Dst, B, *I3, SetRVal(St, B, Result), location, Result);
2169 }
Ted Kremenekafba4b22008-01-16 00:53:15 +00002170 }
Ted Kremenek68d70a82008-01-15 23:55:06 +00002171 }
Ted Kremenek68d70a82008-01-15 23:55:06 +00002172}
Ted Kremenekd2500ab2008-01-16 18:18:48 +00002173
2174//===----------------------------------------------------------------------===//
Ted Kremenek90960972008-01-30 23:03:39 +00002175// "Assume" logic.
2176//===----------------------------------------------------------------------===//
2177
Ted Kremenekf4b49df2008-02-28 10:21:43 +00002178ValueState* GRExprEngine::Assume(ValueState* St, LVal Cond,
Ted Kremenek6da0f5a2008-04-18 17:20:23 +00002179 bool Assumption, bool& isFeasible) {
2180
2181 St = AssumeAux(St, Cond, Assumption, isFeasible);
Ted Kremenekeef8f1e2008-04-18 19:23:43 +00002182
2183 return isFeasible ? TF->EvalAssume(*this, St, Cond, Assumption, isFeasible)
2184 : St;
Ted Kremenek6da0f5a2008-04-18 17:20:23 +00002185}
2186
2187ValueState* GRExprEngine::AssumeAux(ValueState* St, LVal Cond,
2188 bool Assumption, bool& isFeasible) {
2189
Ted Kremenek6e24a802008-02-01 06:36:40 +00002190 switch (Cond.getSubKind()) {
2191 default:
Ted Kremenek07baa252008-02-21 18:02:17 +00002192 assert (false && "'Assume' not implemented for this LVal.");
Ted Kremenek6e24a802008-02-01 06:36:40 +00002193 return St;
Ted Kremenek6da0f5a2008-04-18 17:20:23 +00002194
Ted Kremenek13f31562008-02-06 00:54:14 +00002195 case lval::SymbolValKind:
2196 if (Assumption)
2197 return AssumeSymNE(St, cast<lval::SymbolVal>(Cond).getSymbol(),
Ted Kremenek8ad19872008-03-07 20:13:31 +00002198 BasicVals.getZeroWithPtrWidth(), isFeasible);
Ted Kremenek13f31562008-02-06 00:54:14 +00002199 else
2200 return AssumeSymEQ(St, cast<lval::SymbolVal>(Cond).getSymbol(),
Ted Kremenek8ad19872008-03-07 20:13:31 +00002201 BasicVals.getZeroWithPtrWidth(), isFeasible);
Ted Kremenek6da0f5a2008-04-18 17:20:23 +00002202
2203
Ted Kremenek1b63a3b2008-02-05 21:52:21 +00002204 case lval::DeclValKind:
Ted Kremenek38706192008-02-22 00:54:56 +00002205 case lval::FuncValKind:
2206 case lval::GotoLabelKind:
Ted Kremenekbe621292008-04-22 21:39:21 +00002207 case lval::StringLiteralValKind:
Ted Kremenek6e24a802008-02-01 06:36:40 +00002208 isFeasible = Assumption;
2209 return St;
Ted Kremenek465f25a2008-04-29 22:17:41 +00002210
2211 case lval::FieldOffsetKind:
2212 return AssumeAux(St, cast<lval::FieldOffset>(Cond).getBase(),
2213 Assumption, isFeasible);
2214
Ted Kremenekc4385b42008-04-29 23:24:44 +00002215 case lval::ArrayOffsetKind:
2216 return AssumeAux(St, cast<lval::ArrayOffset>(Cond).getBase(),
2217 Assumption, isFeasible);
2218
Ted Kremenek1b63a3b2008-02-05 21:52:21 +00002219 case lval::ConcreteIntKind: {
2220 bool b = cast<lval::ConcreteInt>(Cond).getValue() != 0;
Ted Kremenek6e24a802008-02-01 06:36:40 +00002221 isFeasible = b ? Assumption : !Assumption;
2222 return St;
2223 }
2224 }
Ted Kremenek90960972008-01-30 23:03:39 +00002225}
2226
Ted Kremenekf4b49df2008-02-28 10:21:43 +00002227ValueState* GRExprEngine::Assume(ValueState* St, NonLVal Cond,
Ted Kremenek6da0f5a2008-04-18 17:20:23 +00002228 bool Assumption, bool& isFeasible) {
2229
2230 St = AssumeAux(St, Cond, Assumption, isFeasible);
Ted Kremenekeef8f1e2008-04-18 19:23:43 +00002231
2232 return isFeasible ? TF->EvalAssume(*this, St, Cond, Assumption, isFeasible)
2233 : St;
Ted Kremenek6da0f5a2008-04-18 17:20:23 +00002234}
2235
2236ValueState* GRExprEngine::AssumeAux(ValueState* St, NonLVal Cond,
2237 bool Assumption, bool& isFeasible) {
Ted Kremenek90960972008-01-30 23:03:39 +00002238 switch (Cond.getSubKind()) {
2239 default:
Ted Kremenek07baa252008-02-21 18:02:17 +00002240 assert (false && "'Assume' not implemented for this NonLVal.");
Ted Kremenek90960972008-01-30 23:03:39 +00002241 return St;
2242
Ted Kremenekab359c12008-02-06 17:32:17 +00002243
2244 case nonlval::SymbolValKind: {
Ted Kremenek5bde36b2008-02-12 21:37:25 +00002245 nonlval::SymbolVal& SV = cast<nonlval::SymbolVal>(Cond);
Ted Kremenekab359c12008-02-06 17:32:17 +00002246 SymbolID sym = SV.getSymbol();
2247
2248 if (Assumption)
Ted Kremenek8ad19872008-03-07 20:13:31 +00002249 return AssumeSymNE(St, sym, BasicVals.getValue(0, SymMgr.getType(sym)),
Ted Kremenekab359c12008-02-06 17:32:17 +00002250 isFeasible);
2251 else
Ted Kremenek8ad19872008-03-07 20:13:31 +00002252 return AssumeSymEQ(St, sym, BasicVals.getValue(0, SymMgr.getType(sym)),
Ted Kremenekab359c12008-02-06 17:32:17 +00002253 isFeasible);
2254 }
2255
Ted Kremenek0033fbb2008-02-06 04:31:33 +00002256 case nonlval::SymIntConstraintValKind:
2257 return
2258 AssumeSymInt(St, Assumption,
2259 cast<nonlval::SymIntConstraintVal>(Cond).getConstraint(),
2260 isFeasible);
2261
Ted Kremenek1b63a3b2008-02-05 21:52:21 +00002262 case nonlval::ConcreteIntKind: {
2263 bool b = cast<nonlval::ConcreteInt>(Cond).getValue() != 0;
Ted Kremenek90960972008-01-30 23:03:39 +00002264 isFeasible = b ? Assumption : !Assumption;
2265 return St;
2266 }
Ted Kremenekfe1a0b12008-04-22 21:10:18 +00002267
2268 case nonlval::LValAsIntegerKind: {
2269 return AssumeAux(St, cast<nonlval::LValAsInteger>(Cond).getLVal(),
2270 Assumption, isFeasible);
2271 }
Ted Kremenek90960972008-01-30 23:03:39 +00002272 }
2273}
2274
Ted Kremenekf4b49df2008-02-28 10:21:43 +00002275ValueState*
2276GRExprEngine::AssumeSymNE(ValueState* St, SymbolID sym,
Ted Kremenek13f31562008-02-06 00:54:14 +00002277 const llvm::APSInt& V, bool& isFeasible) {
Ted Kremenekbc965a62008-02-18 22:57:02 +00002278
Ted Kremenek13f31562008-02-06 00:54:14 +00002279 // First, determine if sym == X, where X != V.
Ted Kremenekf4b49df2008-02-28 10:21:43 +00002280 if (const llvm::APSInt* X = St->getSymVal(sym)) {
Ted Kremenek13f31562008-02-06 00:54:14 +00002281 isFeasible = *X != V;
2282 return St;
2283 }
2284
2285 // Second, determine if sym != V.
Ted Kremenekf4b49df2008-02-28 10:21:43 +00002286 if (St->isNotEqual(sym, V)) {
Ted Kremenek13f31562008-02-06 00:54:14 +00002287 isFeasible = true;
2288 return St;
2289 }
2290
2291 // If we reach here, sym is not a constant and we don't know if it is != V.
2292 // Make that assumption.
2293
2294 isFeasible = true;
2295 return StateMgr.AddNE(St, sym, V);
2296}
2297
Ted Kremenekf4b49df2008-02-28 10:21:43 +00002298ValueState*
2299GRExprEngine::AssumeSymEQ(ValueState* St, SymbolID sym,
Ted Kremenek13f31562008-02-06 00:54:14 +00002300 const llvm::APSInt& V, bool& isFeasible) {
2301
2302 // First, determine if sym == X, where X != V.
Ted Kremenekf4b49df2008-02-28 10:21:43 +00002303 if (const llvm::APSInt* X = St->getSymVal(sym)) {
Ted Kremenek13f31562008-02-06 00:54:14 +00002304 isFeasible = *X == V;
2305 return St;
2306 }
2307
2308 // Second, determine if sym != V.
Ted Kremenekf4b49df2008-02-28 10:21:43 +00002309 if (St->isNotEqual(sym, V)) {
Ted Kremenek13f31562008-02-06 00:54:14 +00002310 isFeasible = false;
2311 return St;
2312 }
2313
2314 // If we reach here, sym is not a constant and we don't know if it is == V.
2315 // Make that assumption.
2316
2317 isFeasible = true;
2318 return StateMgr.AddEQ(St, sym, V);
2319}
Ted Kremenek90960972008-01-30 23:03:39 +00002320
Ted Kremenekf4b49df2008-02-28 10:21:43 +00002321ValueState*
2322GRExprEngine::AssumeSymInt(ValueState* St, bool Assumption,
Ted Kremenek0033fbb2008-02-06 04:31:33 +00002323 const SymIntConstraint& C, bool& isFeasible) {
2324
2325 switch (C.getOpcode()) {
2326 default:
2327 // No logic yet for other operators.
Ted Kremenekd4676512008-03-12 21:45:47 +00002328 isFeasible = true;
Ted Kremenek0033fbb2008-02-06 04:31:33 +00002329 return St;
2330
2331 case BinaryOperator::EQ:
2332 if (Assumption)
2333 return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible);
2334 else
2335 return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible);
2336
2337 case BinaryOperator::NE:
2338 if (Assumption)
2339 return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible);
2340 else
2341 return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible);
2342 }
2343}
2344
Ted Kremenek90960972008-01-30 23:03:39 +00002345//===----------------------------------------------------------------------===//
Ted Kremenek3862eb12008-02-14 22:36:46 +00002346// Visualization.
Ted Kremenekd2500ab2008-01-16 18:18:48 +00002347//===----------------------------------------------------------------------===//
2348
Ted Kremenekdd9e97d2008-01-16 21:46:15 +00002349#ifndef NDEBUG
Ted Kremenek30fa28b2008-02-13 17:41:41 +00002350static GRExprEngine* GraphPrintCheckerState;
Ted Kremenek8b41e8c2008-03-07 20:57:30 +00002351static SourceManager* GraphPrintSourceManager;
Ted Kremenek9f597922008-03-11 19:02:40 +00002352static ValueState::CheckerStatePrinter* GraphCheckerStatePrinter;
Ted Kremenek428d39e2008-01-30 23:24:39 +00002353
Ted Kremenekdd9e97d2008-01-16 21:46:15 +00002354namespace llvm {
2355template<>
Ted Kremenek30fa28b2008-02-13 17:41:41 +00002356struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :
Ted Kremenekdd9e97d2008-01-16 21:46:15 +00002357 public DefaultDOTGraphTraits {
Ted Kremenek08cfd832008-02-08 21:10:02 +00002358
Ted Kremenekf4b49df2008-02-28 10:21:43 +00002359 static void PrintVarBindings(std::ostream& Out, ValueState* St) {
Ted Kremenek08cfd832008-02-08 21:10:02 +00002360
2361 Out << "Variables:\\l";
2362
Ted Kremenek3ec7be92008-01-24 22:27:20 +00002363 bool isFirst = true;
2364
Ted Kremenekf4b49df2008-02-28 10:21:43 +00002365 for (ValueState::vb_iterator I=St->vb_begin(), E=St->vb_end(); I!=E;++I) {
Ted Kremenek08cfd832008-02-08 21:10:02 +00002366
2367 if (isFirst)
2368 isFirst = false;
2369 else
2370 Out << "\\l";
2371
2372 Out << ' ' << I.getKey()->getName() << " : ";
2373 I.getData().print(Out);
2374 }
2375
2376 }
2377
Ted Kremenek17c5f112008-02-11 19:21:59 +00002378
Ted Kremenekf4b49df2008-02-28 10:21:43 +00002379 static void PrintSubExprBindings(std::ostream& Out, ValueState* St){
Ted Kremenek17c5f112008-02-11 19:21:59 +00002380
2381 bool isFirst = true;
2382
Ted Kremenekf4b49df2008-02-28 10:21:43 +00002383 for (ValueState::seb_iterator I=St->seb_begin(), E=St->seb_end();I!=E;++I) {
Ted Kremenek17c5f112008-02-11 19:21:59 +00002384
2385 if (isFirst) {
2386 Out << "\\l\\lSub-Expressions:\\l";
2387 isFirst = false;
2388 }
2389 else
2390 Out << "\\l";
2391
2392 Out << " (" << (void*) I.getKey() << ") ";
2393 I.getKey()->printPretty(Out);
2394 Out << " : ";
2395 I.getData().print(Out);
2396 }
2397 }
2398
Ted Kremenekf4b49df2008-02-28 10:21:43 +00002399 static void PrintBlkExprBindings(std::ostream& Out, ValueState* St){
Ted Kremenek17c5f112008-02-11 19:21:59 +00002400
Ted Kremenek08cfd832008-02-08 21:10:02 +00002401 bool isFirst = true;
2402
Ted Kremenekf4b49df2008-02-28 10:21:43 +00002403 for (ValueState::beb_iterator I=St->beb_begin(), E=St->beb_end(); I!=E;++I){
Ted Kremenek3ec7be92008-01-24 22:27:20 +00002404 if (isFirst) {
Ted Kremenek17c5f112008-02-11 19:21:59 +00002405 Out << "\\l\\lBlock-level Expressions:\\l";
Ted Kremenek3ec7be92008-01-24 22:27:20 +00002406 isFirst = false;
2407 }
2408 else
2409 Out << "\\l";
Ted Kremenek08cfd832008-02-08 21:10:02 +00002410
Ted Kremenek17c5f112008-02-11 19:21:59 +00002411 Out << " (" << (void*) I.getKey() << ") ";
2412 I.getKey()->printPretty(Out);
Ted Kremenek3ec7be92008-01-24 22:27:20 +00002413 Out << " : ";
2414 I.getData().print(Out);
2415 }
2416 }
2417
Ted Kremenekf4b49df2008-02-28 10:21:43 +00002418 static void PrintEQ(std::ostream& Out, ValueState* St) {
2419 ValueState::ConstEqTy CE = St->ConstEq;
Ted Kremeneke6536692008-02-06 03:56:15 +00002420
2421 if (CE.isEmpty())
2422 return;
2423
2424 Out << "\\l\\|'==' constraints:";
2425
Ted Kremenek07baa252008-02-21 18:02:17 +00002426 for (ValueState::ConstEqTy::iterator I=CE.begin(), E=CE.end(); I!=E;++I)
Ted Kremeneke6536692008-02-06 03:56:15 +00002427 Out << "\\l $" << I.getKey() << " : " << I.getData()->toString();
2428 }
2429
Ted Kremenekf4b49df2008-02-28 10:21:43 +00002430 static void PrintNE(std::ostream& Out, ValueState* St) {
2431 ValueState::ConstNotEqTy NE = St->ConstNotEq;
Ted Kremeneke6536692008-02-06 03:56:15 +00002432
2433 if (NE.isEmpty())
2434 return;
2435
2436 Out << "\\l\\|'!=' constraints:";
2437
Ted Kremenek07baa252008-02-21 18:02:17 +00002438 for (ValueState::ConstNotEqTy::iterator I=NE.begin(), EI=NE.end();
Ted Kremeneke6536692008-02-06 03:56:15 +00002439 I != EI; ++I){
2440
2441 Out << "\\l $" << I.getKey() << " : ";
2442 bool isFirst = true;
2443
2444 ValueState::IntSetTy::iterator J=I.getData().begin(),
2445 EJ=I.getData().end();
2446 for ( ; J != EJ; ++J) {
2447 if (isFirst) isFirst = false;
2448 else Out << ", ";
2449
2450 Out << (*J)->toString();
2451 }
2452 }
Ted Kremeneka853de62008-02-14 22:54:53 +00002453 }
2454
2455 static std::string getNodeAttributes(const GRExprEngine::NodeTy* N, void*) {
2456
2457 if (GraphPrintCheckerState->isImplicitNullDeref(N) ||
Ted Kremenekbf988d02008-02-19 00:22:37 +00002458 GraphPrintCheckerState->isExplicitNullDeref(N) ||
Ted Kremenekb31af242008-02-28 09:25:22 +00002459 GraphPrintCheckerState->isUndefDeref(N) ||
2460 GraphPrintCheckerState->isUndefStore(N) ||
2461 GraphPrintCheckerState->isUndefControlFlow(N) ||
Ted Kremenek75f32c62008-03-07 19:04:53 +00002462 GraphPrintCheckerState->isExplicitBadDivide(N) ||
2463 GraphPrintCheckerState->isImplicitBadDivide(N) ||
Ted Kremenek43863eb2008-02-29 23:14:48 +00002464 GraphPrintCheckerState->isUndefResult(N) ||
Ted Kremenek9b31f5b2008-02-29 23:53:11 +00002465 GraphPrintCheckerState->isBadCall(N) ||
2466 GraphPrintCheckerState->isUndefArg(N))
Ted Kremeneka853de62008-02-14 22:54:53 +00002467 return "color=\"red\",style=\"filled\"";
2468
Ted Kremenekc2d07202008-02-28 20:32:03 +00002469 if (GraphPrintCheckerState->isNoReturnCall(N))
2470 return "color=\"blue\",style=\"filled\"";
2471
Ted Kremeneka853de62008-02-14 22:54:53 +00002472 return "";
2473 }
Ted Kremeneke6536692008-02-06 03:56:15 +00002474
Ted Kremenek30fa28b2008-02-13 17:41:41 +00002475 static std::string getNodeLabel(const GRExprEngine::NodeTy* N, void*) {
Ted Kremenekdd9e97d2008-01-16 21:46:15 +00002476 std::ostringstream Out;
Ted Kremenekbacd6cd2008-01-23 22:30:44 +00002477
2478 // Program Location.
Ted Kremenekdd9e97d2008-01-16 21:46:15 +00002479 ProgramPoint Loc = N->getLocation();
2480
2481 switch (Loc.getKind()) {
2482 case ProgramPoint::BlockEntranceKind:
2483 Out << "Block Entrance: B"
2484 << cast<BlockEntrance>(Loc).getBlock()->getBlockID();
2485 break;
2486
2487 case ProgramPoint::BlockExitKind:
2488 assert (false);
2489 break;
2490
Ted Kremenek5f6b4422008-04-29 21:04:26 +00002491 case ProgramPoint::PostLoadKind:
Ted Kremenekf05eec42008-06-18 05:34:07 +00002492 case ProgramPoint::PostPurgeDeadSymbolsKind:
Ted Kremenekdd9e97d2008-01-16 21:46:15 +00002493 case ProgramPoint::PostStmtKind: {
Ted Kremenek8b41e8c2008-03-07 20:57:30 +00002494 const PostStmt& L = cast<PostStmt>(Loc);
2495 Stmt* S = L.getStmt();
2496 SourceLocation SLoc = S->getLocStart();
2497
2498 Out << S->getStmtClassName() << ' ' << (void*) S << ' ';
2499 S->printPretty(Out);
Ted Kremenek3ec7be92008-01-24 22:27:20 +00002500
Ted Kremenekf97c6682008-03-09 03:30:59 +00002501 if (SLoc.isFileID()) {
2502 Out << "\\lline="
2503 << GraphPrintSourceManager->getLineNumber(SLoc) << " col="
2504 << GraphPrintSourceManager->getColumnNumber(SLoc) << "\\l";
2505 }
Ted Kremenek80d52d02008-02-07 05:48:01 +00002506
Ted Kremenek43863eb2008-02-29 23:14:48 +00002507 if (GraphPrintCheckerState->isImplicitNullDeref(N))
Ted Kremenek80d52d02008-02-07 05:48:01 +00002508 Out << "\\|Implicit-Null Dereference.\\l";
Ted Kremenek43863eb2008-02-29 23:14:48 +00002509 else if (GraphPrintCheckerState->isExplicitNullDeref(N))
Ted Kremenekae7bdc12008-02-07 06:04:18 +00002510 Out << "\\|Explicit-Null Dereference.\\l";
Ted Kremenek43863eb2008-02-29 23:14:48 +00002511 else if (GraphPrintCheckerState->isUndefDeref(N))
Ted Kremenekb31af242008-02-28 09:25:22 +00002512 Out << "\\|Dereference of undefialied value.\\l";
Ted Kremenek43863eb2008-02-29 23:14:48 +00002513 else if (GraphPrintCheckerState->isUndefStore(N))
Ted Kremenekb31af242008-02-28 09:25:22 +00002514 Out << "\\|Store to Undefined LVal.";
Ted Kremenek75f32c62008-03-07 19:04:53 +00002515 else if (GraphPrintCheckerState->isExplicitBadDivide(N))
2516 Out << "\\|Explicit divide-by zero or undefined value.";
2517 else if (GraphPrintCheckerState->isImplicitBadDivide(N))
2518 Out << "\\|Implicit divide-by zero or undefined value.";
Ted Kremenek43863eb2008-02-29 23:14:48 +00002519 else if (GraphPrintCheckerState->isUndefResult(N))
Ted Kremenekc2d07202008-02-28 20:32:03 +00002520 Out << "\\|Result of operation is undefined.";
Ted Kremenekc2d07202008-02-28 20:32:03 +00002521 else if (GraphPrintCheckerState->isNoReturnCall(N))
2522 Out << "\\|Call to function marked \"noreturn\".";
Ted Kremenek43863eb2008-02-29 23:14:48 +00002523 else if (GraphPrintCheckerState->isBadCall(N))
2524 Out << "\\|Call to NULL/Undefined.";
Ted Kremenek9b31f5b2008-02-29 23:53:11 +00002525 else if (GraphPrintCheckerState->isUndefArg(N))
2526 Out << "\\|Argument in call is undefined";
Ted Kremenek80d52d02008-02-07 05:48:01 +00002527
Ted Kremenekdd9e97d2008-01-16 21:46:15 +00002528 break;
2529 }
2530
2531 default: {
2532 const BlockEdge& E = cast<BlockEdge>(Loc);
2533 Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
2534 << E.getDst()->getBlockID() << ')';
Ted Kremenek90960972008-01-30 23:03:39 +00002535
2536 if (Stmt* T = E.getSrc()->getTerminator()) {
Ted Kremenek8b41e8c2008-03-07 20:57:30 +00002537
2538 SourceLocation SLoc = T->getLocStart();
2539
Ted Kremenek90960972008-01-30 23:03:39 +00002540 Out << "\\|Terminator: ";
Ted Kremenek8b41e8c2008-03-07 20:57:30 +00002541
Ted Kremenek90960972008-01-30 23:03:39 +00002542 E.getSrc()->printTerminator(Out);
2543
Ted Kremenekf97c6682008-03-09 03:30:59 +00002544 if (SLoc.isFileID()) {
2545 Out << "\\lline="
2546 << GraphPrintSourceManager->getLineNumber(SLoc) << " col="
2547 << GraphPrintSourceManager->getColumnNumber(SLoc);
2548 }
Ted Kremenek8b41e8c2008-03-07 20:57:30 +00002549
Ted Kremenekaee121c2008-02-13 23:08:21 +00002550 if (isa<SwitchStmt>(T)) {
2551 Stmt* Label = E.getDst()->getLabel();
2552
2553 if (Label) {
2554 if (CaseStmt* C = dyn_cast<CaseStmt>(Label)) {
2555 Out << "\\lcase ";
2556 C->getLHS()->printPretty(Out);
2557
2558 if (Stmt* RHS = C->getRHS()) {
2559 Out << " .. ";
2560 RHS->printPretty(Out);
2561 }
2562
2563 Out << ":";
2564 }
2565 else {
2566 assert (isa<DefaultStmt>(Label));
2567 Out << "\\ldefault:";
2568 }
2569 }
2570 else
2571 Out << "\\l(implicit) default:";
2572 }
2573 else if (isa<IndirectGotoStmt>(T)) {
Ted Kremenek90960972008-01-30 23:03:39 +00002574 // FIXME
2575 }
2576 else {
2577 Out << "\\lCondition: ";
2578 if (*E.getSrc()->succ_begin() == E.getDst())
2579 Out << "true";
2580 else
2581 Out << "false";
2582 }
2583
2584 Out << "\\l";
2585 }
Ted Kremenek428d39e2008-01-30 23:24:39 +00002586
Ted Kremenekb31af242008-02-28 09:25:22 +00002587 if (GraphPrintCheckerState->isUndefControlFlow(N)) {
2588 Out << "\\|Control-flow based on\\lUndefined value.\\l";
Ted Kremenek428d39e2008-01-30 23:24:39 +00002589 }
Ted Kremenekdd9e97d2008-01-16 21:46:15 +00002590 }
2591 }
2592
Ted Kremenekf4b49df2008-02-28 10:21:43 +00002593 Out << "\\|StateID: " << (void*) N->getState() << "\\|";
Ted Kremenek08cfd832008-02-08 21:10:02 +00002594
Ted Kremenek9f597922008-03-11 19:02:40 +00002595 N->getState()->printDOT(Out, GraphCheckerStatePrinter);
Ted Kremenekbacd6cd2008-01-23 22:30:44 +00002596
Ted Kremenekbacd6cd2008-01-23 22:30:44 +00002597 Out << "\\l";
Ted Kremenekdd9e97d2008-01-16 21:46:15 +00002598 return Out.str();
2599 }
2600};
2601} // end llvm namespace
2602#endif
2603
Ted Kremenek5e1e05c2008-03-07 22:58:01 +00002604#ifndef NDEBUG
Ted Kremenek83f04aa2008-03-12 17:18:20 +00002605
2606template <typename ITERATOR>
2607GRExprEngine::NodeTy* GetGraphNode(ITERATOR I) { return *I; }
2608
2609template <>
2610GRExprEngine::NodeTy*
2611GetGraphNode<llvm::DenseMap<GRExprEngine::NodeTy*, Expr*>::iterator>
2612 (llvm::DenseMap<GRExprEngine::NodeTy*, Expr*>::iterator I) {
2613 return I->first;
2614}
2615
Ted Kremenek5e1e05c2008-03-07 22:58:01 +00002616template <typename ITERATOR>
Ted Kremenekeef8f1e2008-04-18 19:23:43 +00002617static void AddSources(std::vector<GRExprEngine::NodeTy*>& Sources,
Ted Kremenek83f04aa2008-03-12 17:18:20 +00002618 ITERATOR I, ITERATOR E) {
Ted Kremenek5e1e05c2008-03-07 22:58:01 +00002619
Ted Kremenek83f04aa2008-03-12 17:18:20 +00002620 llvm::SmallPtrSet<void*,10> CachedSources;
2621
2622 for ( ; I != E; ++I ) {
2623 GRExprEngine::NodeTy* N = GetGraphNode(I);
2624 void* p = N->getLocation().getRawData();
2625
2626 if (CachedSources.count(p))
2627 continue;
2628
2629 CachedSources.insert(p);
2630
2631 Sources.push_back(N);
2632 }
Ted Kremenek5e1e05c2008-03-07 22:58:01 +00002633}
2634#endif
2635
2636void GRExprEngine::ViewGraph(bool trim) {
Ted Kremeneke44a8302008-03-11 18:25:33 +00002637#ifndef NDEBUG
Ted Kremenek5e1e05c2008-03-07 22:58:01 +00002638 if (trim) {
Ted Kremenekeef8f1e2008-04-18 19:23:43 +00002639 std::vector<NodeTy*> Src;
2640
2641 // Fixme: Migrate over to the new way of adding nodes.
Ted Kremenek83f04aa2008-03-12 17:18:20 +00002642 AddSources(Src, null_derefs_begin(), null_derefs_end());
2643 AddSources(Src, undef_derefs_begin(), undef_derefs_end());
2644 AddSources(Src, explicit_bad_divides_begin(), explicit_bad_divides_end());
2645 AddSources(Src, undef_results_begin(), undef_results_end());
2646 AddSources(Src, bad_calls_begin(), bad_calls_end());
2647 AddSources(Src, undef_arg_begin(), undef_arg_end());
Ted Kremenek2f0c0e12008-03-14 18:14:50 +00002648 AddSources(Src, undef_branches_begin(), undef_branches_end());
Ted Kremenek5e1e05c2008-03-07 22:58:01 +00002649
Ted Kremenekeef8f1e2008-04-18 19:23:43 +00002650 // The new way.
2651 for (BugTypeSet::iterator I=BugTypes.begin(), E=BugTypes.end(); I!=E; ++I)
2652 (*I)->GetErrorNodes(Src);
2653
2654
Ted Kremenek83f04aa2008-03-12 17:18:20 +00002655 ViewGraph(&Src[0], &Src[0]+Src.size());
Ted Kremenek5e1e05c2008-03-07 22:58:01 +00002656 }
Ted Kremeneke44a8302008-03-11 18:25:33 +00002657 else {
2658 GraphPrintCheckerState = this;
2659 GraphPrintSourceManager = &getContext().getSourceManager();
Ted Kremenek9f597922008-03-11 19:02:40 +00002660 GraphCheckerStatePrinter = TF->getCheckerStatePrinter();
Ted Kremeneke44a8302008-03-11 18:25:33 +00002661
Ted Kremenek5e1e05c2008-03-07 22:58:01 +00002662 llvm::ViewGraph(*G.roots_begin(), "GRExprEngine");
Ted Kremeneke44a8302008-03-11 18:25:33 +00002663
2664 GraphPrintCheckerState = NULL;
2665 GraphPrintSourceManager = NULL;
Ted Kremenek9f597922008-03-11 19:02:40 +00002666 GraphCheckerStatePrinter = NULL;
Ted Kremeneke44a8302008-03-11 18:25:33 +00002667 }
2668#endif
2669}
2670
2671void GRExprEngine::ViewGraph(NodeTy** Beg, NodeTy** End) {
2672#ifndef NDEBUG
2673 GraphPrintCheckerState = this;
2674 GraphPrintSourceManager = &getContext().getSourceManager();
Ted Kremenek9f597922008-03-11 19:02:40 +00002675 GraphCheckerStatePrinter = TF->getCheckerStatePrinter();
Ted Kremenek5e1e05c2008-03-07 22:58:01 +00002676
Ted Kremeneke44a8302008-03-11 18:25:33 +00002677 GRExprEngine::GraphTy* TrimmedG = G.Trim(Beg, End);
2678
2679 if (!TrimmedG)
2680 llvm::cerr << "warning: Trimmed ExplodedGraph is empty.\n";
2681 else {
2682 llvm::ViewGraph(*TrimmedG->roots_begin(), "TrimmedGRExprEngine");
2683 delete TrimmedG;
2684 }
Ted Kremenek5e1e05c2008-03-07 22:58:01 +00002685
Ted Kremenek428d39e2008-01-30 23:24:39 +00002686 GraphPrintCheckerState = NULL;
Ted Kremenek8b41e8c2008-03-07 20:57:30 +00002687 GraphPrintSourceManager = NULL;
Ted Kremenek9f597922008-03-11 19:02:40 +00002688 GraphCheckerStatePrinter = NULL;
Ted Kremenek3862eb12008-02-14 22:36:46 +00002689#endif
Ted Kremenekd2500ab2008-01-16 18:18:48 +00002690}