 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
74.4% |
751 / 1009 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
89.2% |
900 / 1009 |
| |
|
Line Coverage: |
85.0% |
1212 / 1426 |
| |
 |
|
 |
1 : //=-- GRExprEngine.cpp - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This 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.
13 : //
14 : //===----------------------------------------------------------------------===//
15 : #include "GRExprEngineInternalChecks.h"
16 : #include "clang/Checker/PathSensitive/GRExprEngine.h"
17 : #include "clang/Checker/PathSensitive/GRExprEngineBuilders.h"
18 : #include "clang/Checker/PathSensitive/Checker.h"
19 : #include "clang/AST/CharUnits.h"
20 : #include "clang/AST/ParentMap.h"
21 : #include "clang/AST/StmtObjC.h"
22 : #include "clang/Basic/Builtins.h"
23 : #include "clang/Basic/SourceManager.h"
24 : #include "clang/Basic/SourceManager.h"
25 : #include "clang/Basic/PrettyStackTrace.h"
26 : #include "llvm/Support/raw_ostream.h"
27 : #include "llvm/ADT/ImmutableList.h"
28 : #include "llvm/ADT/StringSwitch.h"
29 :
30 : #ifndef NDEBUG
31 : #include "llvm/Support/GraphWriter.h"
32 : #endif
33 :
34 : using namespace clang;
35 : using llvm::dyn_cast;
36 : using llvm::dyn_cast_or_null;
37 : using llvm::cast;
38 : using llvm::APSInt;
39 :
40 : //===----------------------------------------------------------------------===//
41 : // Utility functions.
42 : //===----------------------------------------------------------------------===//
43 :
44 : static inline Selector GetNullarySelector(const char* name, ASTContext& Ctx) {
45 : IdentifierInfo* II = &Ctx.Idents.get(name);
46 : return Ctx.Selectors.getSelector(0, &II);
47 : }
48 :
49 :
50 1689: static QualType GetCalleeReturnType(const CallExpr *CE) {
51 1689: const Expr *Callee = CE->getCallee();
52 1689: QualType T = Callee->getType();
1637: branch 2 taken
52: branch 3 taken
53 1689: if (const PointerType *PT = T->getAs<PointerType>()) {
54 1637: const FunctionType *FT = PT->getPointeeType()->getAs<FunctionType>();
55 1637: T = FT->getResultType();
56 : }
57 : else {
58 52: const BlockPointerType *BT = T->getAs<BlockPointerType>();
59 52: T = BT->getPointeeType()->getAs<FunctionType>()->getResultType();
60 : }
61 : return T;
62 : }
63 :
64 1683: static bool CalleeReturnsReference(const CallExpr *CE) {
65 1683: return (bool) GetCalleeReturnType(CE)->getAs<ReferenceType>();
66 : }
67 :
68 1267: static bool ReceiverReturnsReference(const ObjCMessageExpr *ME) {
69 1267: const ObjCMethodDecl *MD = ME->getMethodDecl();
2: branch 0 taken
1265: branch 1 taken
70 1267: if (!MD)
71 2: return false;
72 1265: return MD->getResultType()->getAs<ReferenceType>();
73 : }
74 :
75 : #ifndef NDEBUG
76 4: static bool ReceiverReturnsReferenceOrRecord(const ObjCMessageExpr *ME) {
77 4: const ObjCMethodDecl *MD = ME->getMethodDecl();
0: branch 0 not taken
4: branch 1 taken
78 4: if (!MD)
79 0: return false;
80 4: QualType T = MD->getResultType();
2: branch 2 taken
2: branch 3 taken
2: branch 6 taken
0: branch 7 not taken
81 4: return T->getAs<RecordType>() || T->getAs<ReferenceType>();
82 : }
83 :
84 6: static bool CalleeReturnsReferenceOrRecord(const CallExpr *CE) {
85 6: QualType T = GetCalleeReturnType(CE);
2: branch 2 taken
4: branch 3 taken
2: branch 6 taken
0: branch 7 not taken
86 6: return T->getAs<ReferenceType>() || T->getAs<RecordType>();
87 : }
88 : #endif
89 :
90 : //===----------------------------------------------------------------------===//
91 : // Batch auditor. DEPRECATED.
92 : //===----------------------------------------------------------------------===//
93 :
94 : namespace {
95 :
96 : class MappedBatchAuditor : public GRSimpleAPICheck {
97 : typedef llvm::ImmutableList<GRSimpleAPICheck*> Checks;
98 : typedef llvm::DenseMap<void*,Checks> MapTy;
99 :
100 : MapTy M;
101 : Checks::Factory F;
102 : Checks AllStmts;
103 :
104 : public:
105 2138: MappedBatchAuditor(llvm::BumpPtrAllocator& Alloc) :
106 2138: F(Alloc), AllStmts(F.GetEmptyList()) {}
107 :
108 2138: virtual ~MappedBatchAuditor() {
109 2138: llvm::DenseSet<GRSimpleAPICheck*> AlreadyVisited;
110 :
4276: branch 5 taken
2138: branch 6 taken
0: branch 12 not taken
0: branch 13 not taken
111 6414: for (MapTy::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI)
6414: branch 6 taken
4276: branch 7 taken
0: branch 14 not taken
0: branch 15 not taken
112 10690: for (Checks::iterator I=MI->second.begin(), E=MI->second.end(); I!=E;++I){
113 :
114 6414: GRSimpleAPICheck* check = *I;
115 :
0: branch 1 not taken
6414: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
116 6414: if (AlreadyVisited.count(check))
117 0: continue;
118 :
119 6414: AlreadyVisited.insert(check);
6414: branch 0 taken
0: branch 1 not taken
6414: branch 3 taken
6414: branch 4 taken
120 6414: delete check;
121 2138: }
2138: branch 3 taken
0: branch 4 not taken
0: branch 9 not taken
0: branch 10 not taken
122 2138: }
123 :
124 6414: void AddCheck(GRSimpleAPICheck *A, Stmt::StmtClass C) {
0: branch 0 not taken
6414: branch 1 taken
125 6414: assert (A && "Check cannot be null.");
126 6414: void* key = reinterpret_cast<void*>((uintptr_t) C);
127 6414: MapTy::iterator I = M.find(key);
4276: branch 4 taken
2138: branch 5 taken
128 6414: M[key] = F.Concat(A, I == M.end() ? F.GetEmptyList() : I->second);
129 6414: }
130 :
131 0: void AddCheck(GRSimpleAPICheck *A) {
0: branch 0 not taken
0: branch 1 not taken
132 0: assert (A && "Check cannot be null.");
133 0: AllStmts = F.Concat(A, AllStmts);
134 0: }
135 :
136 32634: virtual bool Audit(ExplodedNode* N, GRStateManager& VMgr) {
137 : // First handle the auditors that accept all statements.
138 32634: bool isSink = false;
0: branch 4 not taken
32634: branch 5 taken
139 32634: for (Checks::iterator I = AllStmts.begin(), E = AllStmts.end(); I!=E; ++I)
140 0: isSink |= (*I)->Audit(N, VMgr);
141 :
142 : // Next handle the auditors that accept only specific statements.
143 32634: const Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
144 32634: void* key = reinterpret_cast<void*>((uintptr_t) S->getStmtClass());
145 32634: MapTy::iterator MI = M.find(key);
2777: branch 3 taken
29857: branch 4 taken
146 32634: if (MI != M.end()) {
4352: branch 6 taken
2777: branch 7 taken
147 7129: for (Checks::iterator I=MI->second.begin(), E=MI->second.end(); I!=E; ++I)
148 4352: isSink |= (*I)->Audit(N, VMgr);
149 : }
150 :
151 32634: return isSink;
152 : }
153 : };
154 :
155 : } // end anonymous namespace
156 :
157 : //===----------------------------------------------------------------------===//
158 : // Checker worklist routines.
159 : //===----------------------------------------------------------------------===//
160 :
161 : void GRExprEngine::CheckerVisit(Stmt *S, ExplodedNodeSet &Dst,
162 23892: ExplodedNodeSet &Src, bool isPrevisit) {
163 :
0: branch 1 not taken
23892: branch 2 taken
164 23892: if (Checkers.empty()) {
165 0: Dst.insert(Src);
166 0: return;
167 : }
168 :
169 23892: ExplodedNodeSet Tmp;
170 23892: ExplodedNodeSet *PrevSet = &Src;
171 :
533732: branch 4 taken
23892: branch 5 taken
172 557624: for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end(); I!=E;++I){
173 533732: ExplodedNodeSet *CurrSet = 0;
23892: branch 2 taken
509840: branch 3 taken
174 533732: if (I+1 == E)
175 23892: CurrSet = &Dst;
176 : else {
257875: branch 0 taken
251965: branch 1 taken
177 509840: CurrSet = (PrevSet == &Tmp) ? &Src : &Tmp;
178 509840: CurrSet->clear();
179 : }
180 533732: void *tag = I->first;
181 533732: Checker *checker = I->second;
182 :
523506: branch 4 taken
533732: branch 5 taken
183 1057238: for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
184 : NI != NE; ++NI)
185 523506: checker->GR_Visit(*CurrSet, *Builder, *this, S, *NI, tag, isPrevisit);
186 533732: PrevSet = CurrSet;
187 23892: }
188 :
189 : // Don't autotransition. The CheckerContext objects should do this
190 : // automatically.
191 : }
192 :
193 : void GRExprEngine::CheckerEvalNilReceiver(const ObjCMessageExpr *ME,
194 : ExplodedNodeSet &Dst,
195 : const GRState *state,
196 44: ExplodedNode *Pred) {
197 44: bool Evaluated = false;
198 44: ExplodedNodeSet DstTmp;
199 :
132: branch 4 taken
0: branch 5 not taken
200 132: for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end();I!=E;++I) {
201 132: void *tag = I->first;
202 132: Checker *checker = I->second;
203 :
44: branch 1 taken
88: branch 2 taken
204 132: if (checker->GR_EvalNilReceiver(DstTmp, *Builder, *this, ME, Pred, state,
205 : tag)) {
206 44: Evaluated = true;
207 44: break;
208 : } else
209 : // The checker didn't evaluate the expr. Restore the Dst.
210 88: DstTmp.clear();
211 : }
212 :
44: branch 0 taken
0: branch 1 not taken
213 44: if (Evaluated)
214 44: Dst.insert(DstTmp);
215 : else
216 0: Dst.insert(Pred);
217 44: }
218 :
219 : // CheckerEvalCall returns true if one of the checkers processed the node.
220 : // This may return void when all call evaluation logic goes to some checker
221 : // in the future.
222 : bool GRExprEngine::CheckerEvalCall(const CallExpr *CE,
223 : ExplodedNodeSet &Dst,
224 1646: ExplodedNode *Pred) {
225 1646: bool Evaluated = false;
226 1646: ExplodedNodeSet DstTmp;
227 :
35303: branch 4 taken
1520: branch 5 taken
228 36823: for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end();I!=E;++I) {
229 35303: void *tag = I->first;
230 35303: Checker *checker = I->second;
231 :
126: branch 1 taken
35177: branch 2 taken
232 35303: if (checker->GR_EvalCallExpr(DstTmp, *Builder, *this, CE, Pred, tag)) {
233 126: Evaluated = true;
234 126: break;
235 : } else
236 : // The checker didn't evaluate the expr. Restore the DstTmp set.
237 35177: DstTmp.clear();
238 : }
239 :
126: branch 0 taken
1520: branch 1 taken
240 1646: if (Evaluated)
241 126: Dst.insert(DstTmp);
242 : else
243 1520: Dst.insert(Pred);
244 :
245 1646: return Evaluated;
246 : }
247 :
248 : // FIXME: This is largely copy-paste from CheckerVisit(). Need to
249 : // unify.
250 : void GRExprEngine::CheckerVisitBind(const Stmt *AssignE, const Stmt *StoreE,
251 : ExplodedNodeSet &Dst,
252 : ExplodedNodeSet &Src,
253 3974: SVal location, SVal val, bool isPrevisit) {
254 :
0: branch 1 not taken
3974: branch 2 taken
255 3974: if (Checkers.empty()) {
256 0: Dst.insert(Src);
257 0: return;
258 : }
259 :
260 3974: ExplodedNodeSet Tmp;
261 3974: ExplodedNodeSet *PrevSet = &Src;
262 :
90018: branch 4 taken
3974: branch 5 taken
263 93992: for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end(); I!=E; ++I)
264 : {
265 90018: ExplodedNodeSet *CurrSet = 0;
3974: branch 2 taken
86044: branch 3 taken
266 90018: if (I+1 == E)
267 3974: CurrSet = &Dst;
268 : else {
43432: branch 0 taken
42612: branch 1 taken
269 86044: CurrSet = (PrevSet == &Tmp) ? &Src : &Tmp;
270 86044: CurrSet->clear();
271 : }
272 :
273 90018: void *tag = I->first;
274 90018: Checker *checker = I->second;
275 :
90011: branch 4 taken
90018: branch 5 taken
276 180029: for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
277 : NI != NE; ++NI)
278 : checker->GR_VisitBind(*CurrSet, *Builder, *this, AssignE, StoreE,
279 90011: *NI, tag, location, val, isPrevisit);
280 :
281 : // Update which NodeSet is the current one.
282 90018: PrevSet = CurrSet;
283 3974: }
284 :
285 : // Don't autotransition. The CheckerContext objects should do this
286 : // automatically.
287 : }
288 : //===----------------------------------------------------------------------===//
289 : // Engine construction and deletion.
290 : //===----------------------------------------------------------------------===//
291 :
292 2138: static void RegisterInternalChecks(GRExprEngine &Eng) {
293 : // Register internal "built-in" BugTypes with the BugReporter. These BugTypes
294 : // are different than what probably many checks will do since they don't
295 : // create BugReports on-the-fly but instead wait until GRExprEngine finishes
296 : // analyzing a function. Generation of BugReport objects is done via a call
297 : // to 'FlushReports' from BugReporter.
298 : // The following checks do not need to have their associated BugTypes
299 : // explicitly registered with the BugReporter. If they issue any BugReports,
300 : // their associated BugType will get registered with the BugReporter
301 : // automatically. Note that the check itself is owned by the GRExprEngine
302 : // object.
303 2138: RegisterAdjustedReturnValueChecker(Eng);
304 2138: RegisterAttrNonNullChecker(Eng);
305 2138: RegisterCallAndMessageChecker(Eng);
306 2138: RegisterDereferenceChecker(Eng);
307 2138: RegisterVLASizeChecker(Eng);
308 2138: RegisterDivZeroChecker(Eng);
309 2138: RegisterReturnStackAddressChecker(Eng);
310 2138: RegisterReturnUndefChecker(Eng);
311 2138: RegisterUndefinedArraySubscriptChecker(Eng);
312 2138: RegisterUndefinedAssignmentChecker(Eng);
313 2138: RegisterUndefBranchChecker(Eng);
314 2138: RegisterUndefResultChecker(Eng);
315 :
316 : // This is not a checker yet.
317 2138: RegisterNoReturnFunctionChecker(Eng);
318 2138: RegisterBuiltinFunctionChecker(Eng);
319 2138: RegisterOSAtomicChecker(Eng);
320 2138: }
321 :
322 2138: GRExprEngine::GRExprEngine(AnalysisManager &mgr, GRTransferFuncs *tf)
323 : : AMgr(mgr),
324 : CoreEngine(mgr.getASTContext(), *this),
325 : G(CoreEngine.getGraph()),
326 : Builder(NULL),
327 : StateMgr(G.getContext(), mgr.getStoreManagerCreator(),
328 : mgr.getConstraintManagerCreator(), G.getAllocator(),
329 : *this),
330 : SymMgr(StateMgr.getSymbolManager()),
331 : ValMgr(StateMgr.getValueManager()),
332 : SVator(ValMgr.getSValuator()),
333 : CurrentStmt(NULL),
334 : NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
335 : RaiseSel(GetNullarySelector("raise", G.getContext())),
336 2138: BR(mgr, *this), TF(tf) {
337 : // Register internal checks.
338 2138: RegisterInternalChecks(*this);
339 :
340 : // FIXME: Eventually remove the TF object entirely.
341 2138: TF->RegisterChecks(*this);
342 2138: TF->RegisterPrinters(getStateManager().Printers);
343 2138: }
344 :
345 2138: GRExprEngine::~GRExprEngine() {
346 2138: BR.FlushReports();
2138: branch 0 taken
2138: branch 1 taken
12: branch 3 taken
2126: branch 4 taken
12: branch 6 taken
12: branch 7 taken
347 2138: delete [] NSExceptionInstanceRaiseSelectors;
0: branch 4 not taken
0: branch 5 not taken
47866: branch 10 taken
2138: branch 11 taken
0: branch 16 not taken
0: branch 17 not taken
348 50004: for (CheckersOrdered::iterator I=Checkers.begin(), E=Checkers.end(); I!=E;++I)
0: branch 1 not taken
0: branch 2 not taken
47866: branch 5 taken
0: branch 6 not taken
0: branch 9 not taken
0: branch 10 not taken
349 47866: delete I->second;
0: branch 8 not taken
0: branch 9 not taken
0: branch 19 not taken
2138: branch 20 taken
0: branch 30 not taken
0: branch 31 not taken
350 2138: }
351 :
352 : //===----------------------------------------------------------------------===//
353 : // Utility methods.
354 : //===----------------------------------------------------------------------===//
355 :
356 6414: void GRExprEngine::AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C) {
2138: branch 1 taken
4276: branch 2 taken
357 6414: if (!BatchAuditor)
358 2138: BatchAuditor.reset(new MappedBatchAuditor(getGraph().getAllocator()));
359 :
360 6414: ((MappedBatchAuditor*) BatchAuditor.get())->AddCheck(A, C);
361 6414: }
362 :
363 0: void GRExprEngine::AddCheck(GRSimpleAPICheck *A) {
0: branch 1 not taken
0: branch 2 not taken
364 0: if (!BatchAuditor)
365 0: BatchAuditor.reset(new MappedBatchAuditor(getGraph().getAllocator()));
366 :
367 0: ((MappedBatchAuditor*) BatchAuditor.get())->AddCheck(A);
368 0: }
369 :
370 2138: const GRState* GRExprEngine::getInitialState(const LocationContext *InitLoc) {
371 2138: const GRState *state = StateMgr.getInitialState(InitLoc);
372 :
373 : // Preconditions.
374 :
375 : // FIXME: It would be nice if we had a more general mechanism to add
376 : // such preconditions. Some day.
377 : do {
378 2138: const Decl *D = InitLoc->getDecl();
1847: branch 1 taken
291: branch 2 taken
379 2138: if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
380 : // Precondition: the first argument of 'main' is an integer guaranteed
381 : // to be > 0.
382 1847: const IdentifierInfo *II = FD->getIdentifier();
1839: branch 0 taken
8: branch 1 taken
20: branch 5 taken
1819: branch 6 taken
0: branch 8 not taken
20: branch 9 taken
1827: branch 10 taken
20: branch 11 taken
383 1847: if (!II || !(II->getName() == "main" && FD->getNumParams() > 0))
384 1827: break;
385 :
386 20: const ParmVarDecl *PD = FD->getParamDecl(0);
387 20: QualType T = PD->getType();
0: branch 2 not taken
20: branch 3 taken
388 20: if (!T->isIntegerType())
389 0: break;
390 :
391 20: const MemRegion *R = state->getRegion(PD, InitLoc);
0: branch 0 not taken
20: branch 1 taken
392 20: if (!R)
393 0: break;
394 :
395 20: SVal V = state->getSVal(loc::MemRegionVal(R));
396 : SVal Constraint_untested = EvalBinOp(state, BinaryOperator::GT, V,
397 : ValMgr.makeZeroVal(T),
398 20: getContext().IntTy);
399 :
400 : DefinedOrUnknownSVal *Constraint =
401 20: dyn_cast<DefinedOrUnknownSVal>(&Constraint_untested);
402 :
20: branch 0 taken
0: branch 1 not taken
403 20: if (!Constraint)
404 : break;
405 :
20: branch 2 taken
0: branch 3 not taken
406 20: if (const GRState *newState = state->Assume(*Constraint, true))
407 20: state = newState;
408 :
409 20: break;
410 : }
411 :
267: branch 1 taken
24: branch 2 taken
412 291: if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
413 : // Precondition: 'self' is always non-null upon entry to an Objective-C
414 : // method.
415 267: const ImplicitParamDecl *SelfD = MD->getSelfDecl();
416 267: const MemRegion *R = state->getRegion(SelfD, InitLoc);
417 267: SVal V = state->getSVal(loc::MemRegionVal(R));
418 :
212: branch 1 taken
55: branch 2 taken
419 267: if (const Loc *LV = dyn_cast<Loc>(&V)) {
420 : // Assume that the pointer value in 'self' is non-null.
421 212: state = state->Assume(*LV, true);
0: branch 0 not taken
212: branch 1 taken
422 212: assert(state && "'self' cannot be null");
423 267: }
424 : }
425 : } while (0);
426 :
427 2138: return state;
428 : }
429 :
430 : //===----------------------------------------------------------------------===//
431 : // Top-level transfer function logic (Dispatcher).
432 : //===----------------------------------------------------------------------===//
433 :
434 : /// EvalAssume - Called by ConstraintManager. Used to call checker-specific
435 : /// logic for handling assumptions on symbolic values.
436 : const GRState *GRExprEngine::ProcessAssume(const GRState *state, SVal cond,
437 27280: bool assumption) {
366816: branch 4 taken
15777: branch 5 taken
438 382593: for (CheckersOrdered::iterator I = Checkers.begin(), E = Checkers.end();
439 : I != E; ++I) {
440 :
11503: branch 0 taken
355313: branch 1 taken
441 366816: if (!state)
442 11503: return NULL;
443 :
444 355313: state = I->second->EvalAssume(state, cond, assumption);
445 : }
446 :
0: branch 0 not taken
15777: branch 1 taken
447 15777: if (!state)
448 0: return NULL;
449 :
450 15777: return TF->EvalAssume(state, cond, assumption);
451 : }
452 :
453 11886: void GRExprEngine::ProcessStmt(CFGElement CE, GRStmtNodeBuilder& builder) {
454 11886: CurrentStmt = CE.getStmt();
455 : PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
456 : CurrentStmt->getLocStart(),
457 11886: "Error evaluating statement");
458 :
459 11886: Builder = &builder;
460 11886: EntryNode = builder.getLastNode();
461 :
462 : // Set up our simple checks.
11886: branch 1 taken
0: branch 2 not taken
463 11886: if (BatchAuditor)
464 11886: Builder->setAuditor(BatchAuditor.get());
465 :
466 : // Create the cleaned state.
467 11886: const ExplodedNode *BasePred = Builder->getBasePredecessor();
468 : SymbolReaper SymReaper(BasePred->getLiveVariables(), SymMgr,
469 11886: BasePred->getLocationContext()->getCurrentStackFrame());
470 : CleanedState = AMgr.shouldPurgeDead()
471 : ? StateMgr.RemoveDeadBindings(EntryNode->getState(), CurrentStmt, SymReaper)
11706: branch 1 taken
180: branch 2 taken
472 11886: : EntryNode->getState();
473 :
474 : // Process any special transfer function for dead symbols.
475 11886: ExplodedNodeSet Tmp;
476 :
10975: branch 1 taken
911: branch 2 taken
477 11886: if (!SymReaper.hasDeadSymbols())
478 10975: Tmp.Add(EntryNode);
479 : else {
480 911: SaveAndRestore<bool> OldSink(Builder->BuildSinks);
481 911: SaveOr OldHasGen(Builder->HasGeneratedNode);
482 :
483 911: SaveAndRestore<bool> OldPurgeDeadSymbols(Builder->PurgingDeadSymbols);
484 911: Builder->PurgingDeadSymbols = true;
485 :
486 : // FIXME: This should soon be removed.
487 911: ExplodedNodeSet Tmp2;
488 : getTF().EvalDeadSymbols(Tmp2, *this, *Builder, EntryNode, CurrentStmt,
489 911: CleanedState, SymReaper);
490 :
0: branch 1 not taken
911: branch 2 taken
491 911: if (Checkers.empty())
492 0: Tmp.insert(Tmp2);
493 : else {
494 911: ExplodedNodeSet Tmp3;
495 911: ExplodedNodeSet *SrcSet = &Tmp2;
19985: branch 4 taken
911: branch 5 taken
496 20896: for (CheckersOrdered::iterator I = Checkers.begin(), E = Checkers.end();
497 : I != E; ++I) {
498 19985: ExplodedNodeSet *DstSet = 0;
911: branch 2 taken
19074: branch 3 taken
499 19985: if (I+1 == E)
500 911: DstSet = &Tmp;
501 : else {
9652: branch 0 taken
9422: branch 1 taken
502 19074: DstSet = (SrcSet == &Tmp2) ? &Tmp3 : &Tmp2;
503 19074: DstSet->clear();
504 : }
505 :
506 19985: void *tag = I->first;
507 19985: Checker *checker = I->second;
18643: branch 4 taken
19985: branch 5 taken
508 38628: for (ExplodedNodeSet::iterator NI = SrcSet->begin(), NE = SrcSet->end();
509 : NI != NE; ++NI)
510 : checker->GR_EvalDeadSymbols(*DstSet, *Builder, *this, CurrentStmt,
511 18643: *NI, SymReaper, tag);
512 19985: SrcSet = DstSet;
513 911: }
514 : }
515 :
911: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
911: branch 3 taken
516 911: if (!Builder->BuildSinks && !Builder->HasGeneratedNode)
517 0: Tmp.Add(EntryNode);
518 : }
519 :
520 11886: bool HasAutoGenerated = false;
521 :
11825: branch 5 taken
11886: branch 6 taken
522 23711: for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
523 :
524 11825: ExplodedNodeSet Dst;
525 :
526 : // Set the cleaned state.
10975: branch 1 taken
850: branch 2 taken
527 11825: Builder->SetCleanedState(*I == EntryNode ? CleanedState : GetState(*I));
528 :
529 : // Visit the statement.
12: branch 1 taken
11813: branch 2 taken
530 11825: if (CE.asLValue())
531 12: VisitLValue(cast<Expr>(CurrentStmt), *I, Dst);
532 : else
533 11813: Visit(CurrentStmt, *I, Dst);
534 :
535 : // Do we need to auto-generate a node? We only need to do this to generate
536 : // a node with a "cleaned" state; GRCoreEngine will actually handle
537 : // auto-transitions for other cases.
11149: branch 1 taken
676: branch 2 taken
318: branch 5 taken
10831: branch 6 taken
318: branch 7 taken
0: branch 8 not taken
318: branch 9 taken
0: branch 10 not taken
318: branch 11 taken
11507: branch 12 taken
538 11825: if (Dst.size() == 1 && *Dst.begin() == EntryNode
539 : && !Builder->HasGeneratedNode && !HasAutoGenerated) {
540 318: HasAutoGenerated = true;
541 318: builder.generateNode(CurrentStmt, GetState(EntryNode), *I);
542 : }
543 : }
544 :
545 : // NULL out these variables to cleanup.
546 11886: CleanedState = NULL;
547 11886: EntryNode = NULL;
548 :
549 11886: CurrentStmt = 0;
550 :
551 11886: Builder = NULL;
552 11886: }
553 :
554 33388: void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
555 : PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
556 : S->getLocStart(),
557 33388: "Error evaluating statement");
558 :
559 : // FIXME: add metadata to the CFG so that we can disable
560 : // this check when we KNOW that there is no block-level subexpression.
561 : // The motivation is that this check requires a hashtable lookup.
562 :
21575: branch 0 taken
11813: branch 1 taken
1695: branch 5 taken
19880: branch 6 taken
1695: branch 7 taken
31693: branch 8 taken
563 33388: if (S != CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(S)) {
564 1695: Dst.Add(Pred);
565 1695: return;
566 : }
567 :
12: branch 1 taken
4362: branch 2 taken
235: branch 3 taken
0: branch 4 not taken
10: branch 5 taken
66: branch 6 taken
3459: branch 7 taken
1683: branch 8 taken
0: branch 9 not taken
144: branch 10 taken
30: branch 11 taken
210: branch 12 taken
10: branch 13 taken
6149: branch 14 taken
2604: branch 15 taken
6: branch 16 taken
6798: branch 17 taken
2: branch 18 taken
111: branch 19 taken
164: branch 20 taken
112: branch 21 taken
20: branch 22 taken
1267: branch 23 taken
0: branch 24 not taken
529: branch 25 taken
1400: branch 26 taken
98: branch 27 taken
10: branch 28 taken
14: branch 29 taken
2: branch 30 taken
2182: branch 31 taken
4: branch 32 taken
568 31693: switch (S->getStmtClass()) {
569 : // C++ stuff we don't support yet.
570 : case Stmt::CXXMemberCallExprClass:
571 : case Stmt::CXXNamedCastExprClass:
572 : case Stmt::CXXStaticCastExprClass:
573 : case Stmt::CXXDynamicCastExprClass:
574 : case Stmt::CXXReinterpretCastExprClass:
575 : case Stmt::CXXConstCastExprClass:
576 : case Stmt::CXXFunctionalCastExprClass:
577 : case Stmt::CXXTypeidExprClass:
578 : case Stmt::CXXBoolLiteralExprClass:
579 : case Stmt::CXXNullPtrLiteralExprClass:
580 : case Stmt::CXXThrowExprClass:
581 : case Stmt::CXXDefaultArgExprClass:
582 : case Stmt::CXXZeroInitValueExprClass:
583 : case Stmt::CXXNewExprClass:
584 : case Stmt::CXXDeleteExprClass:
585 : case Stmt::CXXPseudoDestructorExprClass:
586 : case Stmt::UnresolvedLookupExprClass:
587 : case Stmt::UnaryTypeTraitExprClass:
588 : case Stmt::DependentScopeDeclRefExprClass:
589 : case Stmt::CXXConstructExprClass:
590 : case Stmt::CXXBindTemporaryExprClass:
591 : case Stmt::CXXExprWithTemporariesClass:
592 : case Stmt::CXXTemporaryObjectExprClass:
593 : case Stmt::CXXUnresolvedConstructExprClass:
594 : case Stmt::CXXDependentScopeMemberExprClass:
595 : case Stmt::UnresolvedMemberExprClass:
596 : case Stmt::CXXCatchStmtClass:
597 : case Stmt::CXXTryStmtClass: {
598 12: SaveAndRestore<bool> OldSink(Builder->BuildSinks);
599 12: Builder->BuildSinks = true;
600 12: MakeNode(Dst, S, Pred, GetState(Pred));
601 12: break;
602 : }
603 :
604 : default:
605 : // Cases we intentionally have "default" handle:
606 : // AddrLabelExpr, IntegerLiteral, CharacterLiteral
607 :
608 4362: Dst.Add(Pred); // No-op. Simply propagate the current state unchanged.
609 4362: break;
610 :
611 : case Stmt::ArraySubscriptExprClass:
612 235: VisitArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst, false);
613 235: break;
614 :
615 : case Stmt::AsmStmtClass:
616 0: VisitAsmStmt(cast<AsmStmt>(S), Pred, Dst);
617 0: break;
618 :
619 : case Stmt::BlockDeclRefExprClass:
620 10: VisitBlockDeclRefExpr(cast<BlockDeclRefExpr>(S), Pred, Dst, false);
621 10: break;
622 :
623 : case Stmt::BlockExprClass:
624 66: VisitBlockExpr(cast<BlockExpr>(S), Pred, Dst);
625 66: break;
626 :
627 : case Stmt::BinaryOperatorClass: {
628 3459: BinaryOperator* B = cast<BinaryOperator>(S);
629 :
143: branch 1 taken
3316: branch 2 taken
630 3459: if (B->isLogicalOp()) {
631 143: VisitLogicalExpr(B, Pred, Dst);
632 143: break;
633 : }
34: branch 1 taken
3282: branch 2 taken
634 3316: else if (B->getOpcode() == BinaryOperator::Comma) {
635 34: const GRState* state = GetState(Pred);
636 34: MakeNode(Dst, B, Pred, state->BindExpr(B, state->getSVal(B->getRHS())));
637 34: break;
638 : }
639 :
11: branch 1 taken
3271: branch 2 taken
9: branch 4 taken
2: branch 5 taken
5: branch 7 taken
4: branch 8 taken
7: branch 9 taken
3275: branch 10 taken
640 3282: if (AMgr.shouldEagerlyAssume() &&
641 : (B->isRelationalOp() || B->isEqualityOp())) {
642 7: ExplodedNodeSet Tmp;
643 7: VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp, false);
644 7: EvalEagerlyAssume(Dst, Tmp, cast<Expr>(S));
645 : }
646 : else
647 3275: VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst, false);
648 :
649 3282: break;
650 : }
651 :
652 : case Stmt::CallExprClass:
653 : case Stmt::CXXOperatorCallExprClass: {
654 1683: CallExpr* C = cast<CallExpr>(S);
655 1683: VisitCall(C, Pred, C->arg_begin(), C->arg_end(), Dst, false);
656 1683: break;
657 : }
658 :
659 : // FIXME: ChooseExpr is really a constant. We need to fix
660 : // the CFG do not model them as explicit control-flow.
661 :
662 : case Stmt::ChooseExprClass: { // __builtin_choose_expr
663 0: ChooseExpr* C = cast<ChooseExpr>(S);
664 0: VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
665 0: break;
666 : }
667 :
668 : case Stmt::CompoundAssignOperatorClass:
669 144: VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst, false);
670 144: break;
671 :
672 : case Stmt::CompoundLiteralExprClass:
673 30: VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst, false);
674 30: break;
675 :
676 : case Stmt::ConditionalOperatorClass: { // '?' operator
677 210: ConditionalOperator* C = cast<ConditionalOperator>(S);
678 210: VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
679 210: break;
680 : }
681 :
682 : case Stmt::CXXThisExprClass:
683 10: VisitCXXThisExpr(cast<CXXThisExpr>(S), Pred, Dst);
684 10: break;
685 :
686 : case Stmt::DeclRefExprClass:
687 6149: VisitDeclRefExpr(cast<DeclRefExpr>(S), Pred, Dst, false);
688 6149: break;
689 :
690 : case Stmt::DeclStmtClass:
691 2604: VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
692 2604: break;
693 :
694 : case Stmt::ForStmtClass:
695 : // This case isn't for branch processing, but for handling the
696 : // initialization of a condition variable.
697 6: VisitCondInit(cast<ForStmt>(S)->getConditionVariable(), S, Pred, Dst);
698 6: break;
699 :
700 : case Stmt::ImplicitCastExprClass:
701 : case Stmt::CStyleCastExprClass: {
702 6798: CastExpr* C = cast<CastExpr>(S);
703 6798: VisitCast(C, C->getSubExpr(), Pred, Dst, false);
704 6798: break;
705 : }
706 :
707 : case Stmt::IfStmtClass:
708 : // This case isn't for branch processing, but for handling the
709 : // initialization of a condition variable.
710 2: VisitCondInit(cast<IfStmt>(S)->getConditionVariable(), S, Pred, Dst);
711 2: break;
712 :
713 : case Stmt::InitListExprClass:
714 111: VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst);
715 111: break;
716 :
717 : case Stmt::MemberExprClass:
718 164: VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst, false);
719 164: break;
720 :
721 : case Stmt::ObjCIvarRefExprClass:
722 112: VisitObjCIvarRefExpr(cast<ObjCIvarRefExpr>(S), Pred, Dst, false);
723 112: break;
724 :
725 : case Stmt::ObjCForCollectionStmtClass:
726 20: VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S), Pred, Dst);
727 20: break;
728 :
729 : case Stmt::ObjCMessageExprClass:
730 1267: VisitObjCMessageExpr(cast<ObjCMessageExpr>(S), Pred, Dst, false);
731 1267: break;
732 :
733 : case Stmt::ObjCAtThrowStmtClass: {
734 : // FIXME: This is not complete. We basically treat @throw as
735 : // an abort.
736 0: SaveAndRestore<bool> OldSink(Builder->BuildSinks);
737 0: Builder->BuildSinks = true;
738 0: MakeNode(Dst, S, Pred, GetState(Pred));
739 0: break;
740 : }
741 :
742 : case Stmt::ParenExprClass:
743 529: Visit(cast<ParenExpr>(S)->getSubExpr()->IgnoreParens(), Pred, Dst);
744 529: break;
745 :
746 : case Stmt::ReturnStmtClass:
747 1400: VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst);
748 1400: break;
749 :
750 : case Stmt::SizeOfAlignOfExprClass:
751 98: VisitSizeOfAlignOfExpr(cast<SizeOfAlignOfExpr>(S), Pred, Dst);
752 98: break;
753 :
754 : case Stmt::StmtExprClass: {
755 10: StmtExpr* SE = cast<StmtExpr>(S);
756 :
10: branch 2 taken
0: branch 3 not taken
757 10: if (SE->getSubStmt()->body_empty()) {
758 : // Empty statement expression.
759 : assert(SE->getType() == getContext().VoidTy
10: branch 4 taken
0: branch 5 not taken
760 10: && "Empty statement expression must have void type.");
761 10: Dst.Add(Pred);
762 10: break;
763 : }
764 :
0: branch 4 not taken
0: branch 5 not taken
765 0: if (Expr* LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
766 0: const GRState* state = GetState(Pred);
767 0: MakeNode(Dst, SE, Pred, state->BindExpr(SE, state->getSVal(LastExpr)));
768 : }
769 : else
770 0: Dst.Add(Pred);
771 :
772 0: break;
773 : }
774 :
775 : case Stmt::StringLiteralClass:
776 14: VisitLValue(cast<StringLiteral>(S), Pred, Dst);
777 14: break;
778 :
779 : case Stmt::SwitchStmtClass:
780 : // This case isn't for branch processing, but for handling the
781 : // initialization of a condition variable.
782 2: VisitCondInit(cast<SwitchStmt>(S)->getConditionVariable(), S, Pred, Dst);
783 2: break;
784 :
785 : case Stmt::UnaryOperatorClass: {
786 2182: UnaryOperator *U = cast<UnaryOperator>(S);
13: branch 1 taken
2169: branch 2 taken
13: branch 4 taken
0: branch 5 not taken
13: branch 6 taken
2169: branch 7 taken
787 2182: if (AMgr.shouldEagerlyAssume()&&(U->getOpcode() == UnaryOperator::LNot)) {
788 13: ExplodedNodeSet Tmp;
789 13: VisitUnaryOperator(U, Pred, Tmp, false);
790 13: EvalEagerlyAssume(Dst, Tmp, U);
791 : }
792 : else
793 2169: VisitUnaryOperator(U, Pred, Dst, false);
794 2182: break;
795 : }
796 :
797 : case Stmt::WhileStmtClass:
798 : // This case isn't for branch processing, but for handling the
799 : // initialization of a condition variable.
800 4: VisitCondInit(cast<WhileStmt>(S)->getConditionVariable(), S, Pred, Dst);
801 : break;
31693: branch 1 taken
1695: branch 2 taken
802 33388: }
803 : }
804 :
805 : void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
806 5236: ExplodedNodeSet& Dst) {
807 :
808 : PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
809 : Ex->getLocStart(),
810 5236: "Error evaluating statement");
811 :
812 :
813 5236: Ex = Ex->IgnoreParens();
814 :
5224: branch 0 taken
12: branch 1 taken
12: branch 5 taken
5212: branch 6 taken
12: branch 7 taken
5224: branch 8 taken
815 5236: if (Ex != CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(Ex)){
816 12: Dst.Add(Pred);
817 5214: return;
818 : }
819 :
0: branch 1 not taken
220: branch 2 taken
6: branch 3 taken
16: branch 4 taken
6: branch 5 taken
9: branch 6 taken
4122: branch 7 taken
6: branch 8 taken
214: branch 9 taken
43: branch 10 taken
4: branch 11 taken
8: branch 12 taken
217: branch 13 taken
342: branch 14 taken
1: branch 15 taken
10: branch 16 taken
820 5224: switch (Ex->getStmtClass()) {
821 : // C++ stuff we don't support yet.
822 : case Stmt::CXXExprWithTemporariesClass:
823 : case Stmt::CXXMemberCallExprClass:
824 : case Stmt::CXXZeroInitValueExprClass: {
825 0: SaveAndRestore<bool> OldSink(Builder->BuildSinks);
826 0: Builder->BuildSinks = true;
827 0: MakeNode(Dst, Ex, Pred, GetState(Pred));
828 0: break;
829 : }
830 :
831 : case Stmt::ArraySubscriptExprClass:
832 220: VisitArraySubscriptExpr(cast<ArraySubscriptExpr>(Ex), Pred, Dst, true);
833 : return;
834 :
835 : case Stmt::BinaryOperatorClass:
836 : case Stmt::CompoundAssignOperatorClass:
837 6: VisitBinaryOperator(cast<BinaryOperator>(Ex), Pred, Dst, true);
838 : return;
839 :
840 : case Stmt::BlockDeclRefExprClass:
841 16: VisitBlockDeclRefExpr(cast<BlockDeclRefExpr>(Ex), Pred, Dst, true);
842 : return;
843 :
844 : case Stmt::CallExprClass:
845 : case Stmt::CXXOperatorCallExprClass: {
846 6: CallExpr *C = cast<CallExpr>(Ex);
0: branch 1 not taken
6: branch 2 taken
847 6: assert(CalleeReturnsReferenceOrRecord(C));
848 6: VisitCall(C, Pred, C->arg_begin(), C->arg_end(), Dst, true);
849 6: break;
850 : }
851 :
852 : case Stmt::CompoundLiteralExprClass:
853 9: VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(Ex), Pred, Dst, true);
854 : return;
855 :
856 : case Stmt::DeclRefExprClass:
857 4122: VisitDeclRefExpr(cast<DeclRefExpr>(Ex), Pred, Dst, true);
858 : return;
859 :
860 : case Stmt::ImplicitCastExprClass:
861 : case Stmt::CStyleCastExprClass: {
862 6: CastExpr *C = cast<CastExpr>(Ex);
863 6: QualType T = Ex->getType();
864 6: VisitCast(C, C->getSubExpr(), Pred, Dst, true);
865 6: break;
866 : }
867 :
868 : case Stmt::MemberExprClass:
869 214: VisitMemberExpr(cast<MemberExpr>(Ex), Pred, Dst, true);
870 : return;
871 :
872 : case Stmt::ObjCIvarRefExprClass:
873 43: VisitObjCIvarRefExpr(cast<ObjCIvarRefExpr>(Ex), Pred, Dst, true);
874 : return;
875 :
876 : case Stmt::ObjCMessageExprClass: {
877 4: ObjCMessageExpr *ME = cast<ObjCMessageExpr>(Ex);
0: branch 1 not taken
4: branch 2 taken
878 4: assert(ReceiverReturnsReferenceOrRecord(ME));
879 4: VisitObjCMessageExpr(ME, Pred, Dst, true);
880 : return;
881 : }
882 :
883 : case Stmt::ObjCPropertyRefExprClass:
884 : case Stmt::ObjCImplicitSetterGetterRefExprClass:
885 : // FIXME: Property assignments are lvalues, but not really "locations".
886 : // e.g.: self.x = something;
887 : // Here the "self.x" really can translate to a method call (setter) when
888 : // the assignment is made. Moreover, the entire assignment expression
889 : // evaluate to whatever "something" is, not calling the "getter" for
890 : // the property (which would make sense since it can have side effects).
891 : // We'll probably treat this as a location, but not one that we can
892 : // take the address of. Perhaps we need a new SVal class for cases
893 : // like thsis?
894 : // Note that we have a similar problem for bitfields, since they don't
895 : // have "locations" in the sense that we can take their address.
896 8: Dst.Add(Pred);
897 : return;
898 :
899 : case Stmt::StringLiteralClass: {
900 217: const GRState* state = GetState(Pred);
901 217: SVal V = state->getLValue(cast<StringLiteral>(Ex));
902 217: MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, V));
903 217: return;
904 : }
905 :
906 : case Stmt::UnaryOperatorClass:
907 342: VisitUnaryOperator(cast<UnaryOperator>(Ex), Pred, Dst, true);
908 : return;
909 :
910 : // In C++, binding an rvalue to a reference requires to create an object.
911 : case Stmt::IntegerLiteralClass:
912 1: CreateCXXTemporaryObject(Ex, Pred, Dst);
913 : return;
914 :
915 : default:
916 : // Arbitrary subexpressions can return aggregate temporaries that
917 : // can be used in a lvalue context. We need to enhance our support
918 : // of such temporaries in both the environment and the store, so right
919 : // now we just do a regular visit.
920 : assert ((Ex->getType()->isAggregateType()) &&
921 : "Other kinds of expressions with non-aggregate/union types do"
10: branch 3 taken
0: branch 4 not taken
922 10: " not have lvalues.");
923 :
924 10: Visit(Ex, Pred, Dst);
22: branch 1 taken
5214: branch 2 taken
925 5236: }
926 : }
927 :
928 : //===----------------------------------------------------------------------===//
929 : // Block entrance. (Update counters).
930 : //===----------------------------------------------------------------------===//
931 :
932 : bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, const GRState*,
933 6739: GRBlockCounter BC) {
934 :
935 6739: return BC.getNumVisited(B->getBlockID()) < 3;
936 : }
937 :
938 : //===----------------------------------------------------------------------===//
939 : // Generic node creation.
940 : //===----------------------------------------------------------------------===//
941 :
942 : ExplodedNode* GRExprEngine::MakeNode(ExplodedNodeSet& Dst, Stmt* S,
943 : ExplodedNode* Pred, const GRState* St,
944 25132: ProgramPoint::Kind K, const void *tag) {
0: branch 0 not taken
25132: branch 1 taken
945 25132: assert (Builder && "GRStmtNodeBuilder not present.");
946 25132: SaveAndRestore<const void*> OldTag(Builder->Tag);
947 25132: Builder->Tag = tag;
948 25132: return Builder->MakeNode(Dst, S, Pred, St, K);
949 : }
950 :
951 : //===----------------------------------------------------------------------===//
952 : // Branch processing.
953 : //===----------------------------------------------------------------------===//
954 :
955 : const GRState* GRExprEngine::MarkBranch(const GRState* state,
956 : Stmt* Terminator,
957 3234: bool branchTaken) {
958 :
2823: branch 1 taken
151: branch 2 taken
252: branch 3 taken
8: branch 4 taken
959 3234: switch (Terminator->getStmtClass()) {
960 : default:
961 2823: return state;
962 :
963 : case Stmt::BinaryOperatorClass: { // '&&' and '||'
964 :
965 151: BinaryOperator* B = cast<BinaryOperator>(Terminator);
966 151: BinaryOperator::Opcode Op = B->getOpcode();
967 :
28: branch 0 taken
123: branch 1 taken
0: branch 2 not taken
28: branch 3 taken
968 151: assert (Op == BinaryOperator::LAnd || Op == BinaryOperator::LOr);
969 :
970 : // For &&, if we take the true branch, then the value of the whole
971 : // expression is that of the RHS expression.
972 : //
973 : // For ||, if we take the false branch, then the value of the whole
974 : // expression is that of the RHS expression.
975 :
976 : Expr* Ex = (Op == BinaryOperator::LAnd && branchTaken) ||
977 : (Op == BinaryOperator::LOr && !branchTaken)
123: branch 0 taken
28: branch 1 taken
60: branch 2 taken
63: branch 3 taken
28: branch 4 taken
60: branch 5 taken
14: branch 6 taken
14: branch 7 taken
978 151: ? B->getRHS() : B->getLHS();
979 :
980 151: return state->BindExpr(B, UndefinedVal(Ex));
981 : }
982 :
983 : case Stmt::ConditionalOperatorClass: { // ?:
984 :
985 252: ConditionalOperator* C = cast<ConditionalOperator>(Terminator);
986 :
987 : // For ?, if branchTaken == true then the value is either the LHS or
988 : // the condition itself. (GNU extension).
989 :
990 : Expr* Ex;
991 :
109: branch 0 taken
143: branch 1 taken
992 252: if (branchTaken)
105: branch 1 taken
4: branch 2 taken
993 109: Ex = C->getLHS() ? C->getLHS() : C->getCond();
994 : else
995 143: Ex = C->getRHS();
996 :
997 252: return state->BindExpr(C, UndefinedVal(Ex));
998 : }
999 :
1000 : case Stmt::ChooseExprClass: { // ?:
1001 :
1002 8: ChooseExpr* C = cast<ChooseExpr>(Terminator);
1003 :
4: branch 0 taken
4: branch 1 taken
1004 8: Expr* Ex = branchTaken ? C->getLHS() : C->getRHS();
1005 8: return state->BindExpr(C, UndefinedVal(Ex));
1006 : }
1007 : }
1008 : }
1009 :
1010 : /// RecoverCastedSymbol - A helper function for ProcessBranch that is used
1011 : /// to try to recover some path-sensitivity for casts of symbolic
1012 : /// integers that promote their values (which are currently not tracked well).
1013 : /// This function returns the SVal bound to Condition->IgnoreCasts if all the
1014 : // cast(s) did was sign-extend the original value.
1015 : static SVal RecoverCastedSymbol(GRStateManager& StateMgr, const GRState* state,
1016 197: Stmt* Condition, ASTContext& Ctx) {
1017 :
1018 197: Expr *Ex = dyn_cast<Expr>(Condition);
0: branch 0 not taken
197: branch 1 taken
1019 197: if (!Ex)
1020 0: return UnknownVal();
1021 :
1022 197: uint64_t bits = 0;
1023 197: bool bitsInit = false;
1024 :
0: branch 1 not taken
197: branch 2 taken
1025 197: while (CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
1026 0: QualType T = CE->getType();
1027 :
0: branch 2 not taken
0: branch 3 not taken
1028 0: if (!T->isIntegerType())
1029 0: return UnknownVal();
1030 :
1031 0: uint64_t newBits = Ctx.getTypeSize(T);
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
1032 0: if (!bitsInit || newBits < bits) {
1033 0: bitsInit = true;
1034 0: bits = newBits;
1035 : }
1036 :
1037 0: Ex = CE->getSubExpr();
1038 : }
1039 :
1040 : // We reached a non-cast. Is it a symbolic value?
1041 197: QualType T = Ex->getType();
1042 :
0: branch 0 not taken
197: branch 1 taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 7 not taken
0: branch 8 not taken
197: branch 9 taken
0: branch 10 not taken
1043 197: if (!bitsInit || !T->isIntegerType() || Ctx.getTypeSize(T) > bits)
1044 197: return UnknownVal();
1045 :
1046 0: return state->getSVal(Ex);
1047 : }
1048 :
1049 : void GRExprEngine::ProcessBranch(Stmt* Condition, Stmt* Term,
1050 2262: GRBranchNodeBuilder& builder) {
1051 :
1052 : // Check for NULL conditions; e.g. "for(;;)"
14: branch 0 taken
2248: branch 1 taken
1053 2262: if (!Condition) {
1054 14: builder.markInfeasible(false);
1055 14: return;
1056 : }
1057 :
1058 : PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
1059 : Condition->getLocStart(),
1060 2248: "Error evaluating branch");
1061 :
51280: branch 4 taken
2248: branch 5 taken
1062 53528: for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end();I!=E;++I) {
1063 51280: void *tag = I->first;
1064 51280: Checker *checker = I->second;
1065 51280: checker->VisitBranchCondition(builder, *this, Condition, tag);
1066 : }
1067 :
1068 : // If the branch condition is undefined, return;
103: branch 1 taken
2145: branch 2 taken
30: branch 4 taken
73: branch 5 taken
30: branch 6 taken
2218: branch 7 taken
1069 2248: if (!builder.isFeasible(true) && !builder.isFeasible(false))
1070 227: return;
1071 :
1072 2218: const GRState* PrevState = builder.getState();
1073 2218: SVal X = PrevState->getSVal(Condition);
1074 :
197: branch 1 taken
2021: branch 2 taken
1075 2218: if (X.isUnknown()) {
1076 : // Give it a chance to recover from unknown.
197: branch 1 taken
0: branch 2 not taken
1077 197: if (const Expr *Ex = dyn_cast<Expr>(Condition)) {
197: branch 3 taken
0: branch 4 not taken
1078 197: if (Ex->getType()->isIntegerType()) {
1079 : // Try to recover some path-sensitivity. Right now casts of symbolic
1080 : // integers that promote their values are currently not tracked well.
1081 : // If 'Condition' is such an expression, try and recover the
1082 : // underlying value and use that instead.
1083 : SVal recovered = RecoverCastedSymbol(getStateManager(),
1084 : builder.getState(), Condition,
1085 197: getContext());
1086 :
0: branch 1 not taken
197: branch 2 taken
1087 197: if (!recovered.isUnknown()) {
1088 0: X = recovered;
1089 197: }
1090 : }
1091 : }
1092 : // If the condition is still unknown, give up.
197: branch 1 taken
0: branch 2 not taken
1093 197: if (X.isUnknown()) {
1094 197: builder.generateNode(MarkBranch(PrevState, Term, true), true);
1095 197: builder.generateNode(MarkBranch(PrevState, Term, false), false);
1096 : return;
1097 : }
1098 : }
1099 :
1100 2021: DefinedSVal V = cast<DefinedSVal>(X);
1101 :
1102 : // Process the true branch.
1948: branch 1 taken
73: branch 2 taken
1103 2021: if (builder.isFeasible(true)) {
1458: branch 2 taken
490: branch 3 taken
1104 1948: if (const GRState *state = PrevState->Assume(V, true))
1105 1458: builder.generateNode(MarkBranch(state, Term, true), true);
1106 : else
1107 490: builder.markInfeasible(true);
1108 : }
1109 :
1110 : // Process the false branch.
1885: branch 1 taken
136: branch 2 taken
1111 2021: if (builder.isFeasible(false)) {
1382: branch 2 taken
503: branch 3 taken
1112 1885: if (const GRState *state = PrevState->Assume(V, false))
1113 1382: builder.generateNode(MarkBranch(state, Term, false), false);
1114 : else
1115 503: builder.markInfeasible(false);
2021: branch 2 taken
197: branch 3 taken
2021: branch 5 taken
227: branch 6 taken
1116 2021: }
1117 : }
1118 :
1119 : /// ProcessIndirectGoto - Called by GRCoreEngine. Used to generate successor
1120 : /// nodes by processing the 'effects' of a computed goto jump.
1121 10: void GRExprEngine::ProcessIndirectGoto(GRIndirectGotoNodeBuilder& builder) {
1122 :
1123 10: const GRState *state = builder.getState();
1124 10: SVal V = state->getSVal(builder.getTarget());
1125 :
1126 : // Three possibilities:
1127 : //
1128 : // (1) We know the computed label.
1129 : // (2) The label is NULL (or some other constant), or Undefined.
1130 : // (3) We have no clue about the label. Dispatch to all targets.
1131 : //
1132 :
1133 : typedef GRIndirectGotoNodeBuilder::iterator iterator;
1134 :
0: branch 1 not taken
10: branch 2 taken
1135 10: if (isa<loc::GotoLabel>(V)) {
1136 0: LabelStmt* L = cast<loc::GotoLabel>(V).getLabel();
1137 :
0: branch 4 not taken
0: branch 5 not taken
1138 0: for (iterator I=builder.begin(), E=builder.end(); I != E; ++I) {
0: branch 1 not taken
0: branch 2 not taken
1139 0: if (I.getLabel() == L) {
1140 0: builder.generateNode(I, state);
1141 0: return;
1142 : }
1143 : }
1144 :
1145 0: assert (false && "No block with label.");
1146 : return;
1147 : }
1148 :
10: branch 1 taken
0: branch 2 not taken
0: branch 4 not taken
10: branch 5 taken
0: branch 6 not taken
10: branch 7 taken
1149 10: if (isa<loc::ConcreteInt>(V) || isa<UndefinedVal>(V)) {
1150 : // Dispatch to the first target and mark it as a sink.
1151 : //ExplodedNode* N = builder.generateNode(builder.begin(), state, true);
1152 : // FIXME: add checker visit.
1153 : // UndefBranches.insert(N);
1154 : return;
1155 : }
1156 :
1157 : // This is really a catch-all. We don't support symbolics yet.
1158 : // FIXME: Implement dispatch for symbolic pointers.
1159 :
0: branch 4 not taken
10: branch 5 taken
1160 10: for (iterator I=builder.begin(), E=builder.end(); I != E; ++I)
10: branch 2 taken
0: branch 3 not taken
1161 10: builder.generateNode(I, state);
1162 : }
1163 :
1164 :
1165 : void GRExprEngine::VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R,
1166 210: ExplodedNode* Pred, ExplodedNodeSet& Dst) {
1167 :
1168 : assert(Ex == CurrentStmt &&
210: branch 0 taken
0: branch 1 not taken
0: branch 5 not taken
210: branch 6 taken
1169 210: Pred->getLocationContext()->getCFG()->isBlkExpr(Ex));
1170 :
1171 210: const GRState* state = GetState(Pred);
1172 210: SVal X = state->getSVal(Ex);
1173 :
0: branch 1 not taken
210: branch 2 taken
1174 210: assert (X.isUndef());
1175 :
1176 210: Expr *SE = (Expr*) cast<UndefinedVal>(X).getData();
0: branch 0 not taken
210: branch 1 taken
1177 210: assert(SE);
1178 210: X = state->getSVal(SE);
1179 :
1180 : // Make sure that we invalidate the previous binding.
1181 210: MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, X, true));
1182 210: }
1183 :
1184 : /// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path
1185 : /// nodes when the control reaches the end of a function.
1186 2600: void GRExprEngine::ProcessEndPath(GREndPathNodeBuilder& builder) {
1187 2600: getTF().EvalEndPath(*this, builder);
1188 2600: StateMgr.EndPath(builder.getState());
58696: branch 4 taken
2600: branch 5 taken
1189 61296: for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end(); I!=E;++I){
1190 58696: void *tag = I->first;
1191 58696: Checker *checker = I->second;
1192 58696: checker->EvalEndPath(builder, tag, *this);
1193 : }
1194 2600: }
1195 :
1196 : /// ProcessSwitch - Called by GRCoreEngine. Used to generate successor
1197 : /// nodes by processing the 'effects' of a switch statement.
1198 20: void GRExprEngine::ProcessSwitch(GRSwitchNodeBuilder& builder) {
1199 : typedef GRSwitchNodeBuilder::iterator iterator;
1200 20: const GRState* state = builder.getState();
1201 20: Expr* CondE = builder.getCondition();
1202 20: SVal CondV_untested = state->getSVal(CondE);
1203 :
0: branch 1 not taken
20: branch 2 taken
1204 20: if (CondV_untested.isUndef()) {
1205 : //ExplodedNode* N = builder.generateDefaultCaseNode(state, true);
1206 : // FIXME: add checker
1207 : //UndefBranches.insert(N);
1208 :
1209 0: return;
1210 : }
1211 20: DefinedOrUnknownSVal CondV = cast<DefinedOrUnknownSVal>(CondV_untested);
1212 :
1213 20: const GRState *DefaultSt = state;
1214 20: bool defaultIsFeasible = false;
1215 :
94: branch 3 taken
0: branch 4 not taken
94: branch 6 taken
0: branch 7 not taken
94: branch 10 taken
20: branch 11 taken
1216 114: for (iterator I = builder.begin(), EI = builder.end(); I != EI; ++I) {
1217 94: CaseStmt* Case = cast<CaseStmt>(I.getCase());
1218 :
1219 : // Evaluate the LHS of the case value.
1220 94: Expr::EvalResult V1;
1221 94: bool b = Case->getLHS()->Evaluate(V1, getContext());
1222 :
1223 : // Sanity checks. These go away in Release builds.
1224 : assert(b && V1.Val.isInt() && !V1.HasSideEffects
94: branch 0 taken
0: branch 1 not taken
94: branch 3 taken
0: branch 4 not taken
94: branch 5 taken
0: branch 6 not taken
1225 94: && "Case condition must evaluate to an integer constant.");
1226 94: b = b; // silence unused variable warning
1227 : assert(V1.Val.getInt().getBitWidth() ==
0: branch 5 not taken
94: branch 6 taken
1228 94: getContext().getTypeSize(CondE->getType()));
1229 :
1230 : // Get the RHS of the case, if it exists.
1231 94: Expr::EvalResult V2;
1232 :
4: branch 1 taken
90: branch 2 taken
1233 94: if (Expr* E = Case->getRHS()) {
1234 4: b = E->Evaluate(V2, getContext());
1235 : assert(b && V2.Val.isInt() && !V2.HasSideEffects
4: branch 0 taken
0: branch 1 not taken
4: branch 3 taken
0: branch 4 not taken
4: branch 5 taken
0: branch 6 not taken
1236 4: && "Case condition must evaluate to an integer constant.");
1237 4: b = b; // silence unused variable warning
1238 : }
1239 : else
1240 90: V2 = V1;
1241 :
1242 : // FIXME: Eventually we should replace the logic below with a range
1243 : // comparison, rather than concretize the values within the range.
1244 : // This should be easy once we have "ranges" for NonLVals.
1245 :
1246 40: do {
1247 134: nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1.Val.getInt()));
1248 : DefinedOrUnknownSVal Res = SVator.EvalEQ(DefaultSt ? DefaultSt : state,
134: branch 0 taken
0: branch 1 not taken
1249 134: CondV, CaseVal);
1250 :
1251 : // Now "assume" that the case matches.
134: branch 2 taken
0: branch 3 not taken
1252 134: if (const GRState* stateNew = state->Assume(Res, true)) {
1253 134: builder.generateCaseStmtNode(I, stateNew);
1254 :
1255 : // If CondV evaluates to a constant, then we know that this
1256 : // is the *only* case that we can take, so stop evaluating the
1257 : // others.
0: branch 1 not taken
134: branch 2 taken
1258 134: if (isa<nonloc::ConcreteInt>(CondV))
1259 : return;
1260 : }
1261 :
1262 : // Now "assume" that the case doesn't match. Add this state
1263 : // to the default state (if it is feasible).
134: branch 0 taken
0: branch 1 not taken
1264 134: if (DefaultSt) {
132: branch 2 taken
2: branch 3 taken
1265 134: if (const GRState *stateNew = DefaultSt->Assume(Res, false)) {
1266 132: defaultIsFeasible = true;
1267 132: DefaultSt = stateNew;
1268 : }
1269 : else {
1270 2: defaultIsFeasible = false;
1271 2: DefaultSt = NULL;
1272 : }
1273 : }
1274 :
1275 : // Concretize the next value in the range.
94: branch 3 taken
40: branch 4 taken
1276 134: if (V1.Val.getInt() == V2.Val.getInt())
1277 : break;
1278 :
1279 40: ++V1.Val.getInt();
0: branch 3 not taken
40: branch 4 taken
40: branch 7 taken
0: branch 8 not taken
94: branch 9 taken
40: branch 11 taken
0: branch 12 not taken
94: branch 13 taken
1280 40: assert (V1.Val.getInt() <= V2.Val.getInt());
1281 :
1282 : } while (true);
1283 : }
1284 :
1285 : // If we reach here, than we know that the default branch is
1286 : // possible.
16: branch 0 taken
4: branch 1 taken
20: branch 4 taken
0: branch 5 not taken
20: branch 7 taken
0: branch 8 not taken
1287 20: if (defaultIsFeasible) builder.generateDefaultCaseNode(DefaultSt);
1288 : }
1289 :
1290 : //===----------------------------------------------------------------------===//
1291 : // Transfer functions: logical operations ('&&', '||').
1292 : //===----------------------------------------------------------------------===//
1293 :
1294 : void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
1295 143: ExplodedNodeSet& Dst) {
1296 :
1297 : assert(B->getOpcode() == BinaryOperator::LAnd ||
24: branch 1 taken
119: branch 2 taken
0: branch 4 not taken
24: branch 5 taken
1298 143: B->getOpcode() == BinaryOperator::LOr);
1299 :
143: branch 0 taken
0: branch 1 not taken
0: branch 5 not taken
143: branch 6 taken
1300 143: assert(B==CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(B));
1301 :
1302 143: const GRState* state = GetState(Pred);
1303 143: SVal X = state->getSVal(B);
0: branch 1 not taken
143: branch 2 taken
1304 143: assert(X.isUndef());
1305 :
1306 143: const Expr *Ex = (const Expr*) cast<UndefinedVal>(X).getData();
0: branch 0 not taken
143: branch 1 taken
1307 143: assert(Ex);
1308 :
69: branch 1 taken
74: branch 2 taken
1309 143: if (Ex == B->getRHS()) {
1310 69: X = state->getSVal(Ex);
1311 :
1312 : // Handle undefined values.
0: branch 1 not taken
69: branch 2 taken
1313 69: if (X.isUndef()) {
1314 0: MakeNode(Dst, B, Pred, state->BindExpr(B, X));
1315 0: return;
1316 : }
1317 :
1318 69: DefinedOrUnknownSVal XD = cast<DefinedOrUnknownSVal>(X);
1319 :
1320 : // We took the RHS. Because the value of the '&&' or '||' expression must
1321 : // evaluate to 0 or 1, we must assume the value of the RHS evaluates to 0
1322 : // or 1. Alternatively, we could take a lazy approach, and calculate this
1323 : // value later when necessary. We don't have the machinery in place for
1324 : // this right now, and since most logical expressions are used for branches,
1325 : // the payoff is not likely to be large. Instead, we do eager evaluation.
37: branch 2 taken
32: branch 3 taken
1326 69: if (const GRState *newState = state->Assume(XD, true))
1327 : MakeNode(Dst, B, Pred,
1328 37: newState->BindExpr(B, ValMgr.makeIntVal(1U, B->getType())));
1329 :
54: branch 2 taken
15: branch 3 taken
1330 69: if (const GRState *newState = state->Assume(XD, false))
1331 : MakeNode(Dst, B, Pred,
1332 54: newState->BindExpr(B, ValMgr.makeIntVal(0U, B->getType())));
1333 : }
1334 : else {
1335 : // We took the LHS expression. Depending on whether we are '&&' or
1336 : // '||' we know what the value of the expression is via properties of
1337 : // the short-circuiting.
1338 : X = ValMgr.makeIntVal(B->getOpcode() == BinaryOperator::LAnd ? 0U : 1U,
1339 74: B->getType());
1340 74: MakeNode(Dst, B, Pred, state->BindExpr(B, X));
143: branch 1 taken
0: branch 2 not taken
1341 143: }
1342 : }
1343 :
1344 : //===----------------------------------------------------------------------===//
1345 : // Transfer functions: Loads and stores.
1346 : //===----------------------------------------------------------------------===//
1347 :
1348 : void GRExprEngine::VisitBlockExpr(BlockExpr *BE, ExplodedNode *Pred,
1349 66: ExplodedNodeSet &Dst) {
1350 :
1351 66: ExplodedNodeSet Tmp;
1352 :
1353 66: CanQualType T = getContext().getCanonicalType(BE->getType());
1354 : SVal V = ValMgr.getBlockPointer(BE->getBlockDecl(), T,
1355 66: Pred->getLocationContext());
1356 :
1357 : MakeNode(Tmp, BE, Pred, GetState(Pred)->BindExpr(BE, V),
1358 66: ProgramPoint::PostLValueKind);
1359 :
1360 : // Post-visit the BlockExpr.
1361 66: CheckerVisit(BE, Dst, Tmp, false);
1362 66: }
1363 :
1364 : void GRExprEngine::VisitDeclRefExpr(DeclRefExpr *Ex, ExplodedNode *Pred,
1365 10271: ExplodedNodeSet &Dst, bool asLValue) {
1366 10271: VisitCommonDeclRefExpr(Ex, Ex->getDecl(), Pred, Dst, asLValue);
1367 10271: }
1368 :
1369 : void GRExprEngine::VisitBlockDeclRefExpr(BlockDeclRefExpr *Ex,
1370 : ExplodedNode *Pred,
1371 26: ExplodedNodeSet &Dst, bool asLValue) {
1372 26: VisitCommonDeclRefExpr(Ex, Ex->getDecl(), Pred, Dst, asLValue);
1373 26: }
1374 :
1375 : void GRExprEngine::VisitCommonDeclRefExpr(Expr *Ex, const NamedDecl *D,
1376 : ExplodedNode *Pred,
1377 10297: ExplodedNodeSet &Dst, bool asLValue) {
1378 :
1379 10297: const GRState *state = GetState(Pred);
1380 :
8545: branch 1 taken
1752: branch 2 taken
1381 10297: if (const VarDecl* VD = dyn_cast<VarDecl>(D)) {
1382 :
1383 8545: SVal V = state->getLValue(VD, Pred->getLocationContext());
1384 :
2514: branch 0 taken
6031: branch 1 taken
1385 8545: if (asLValue) {
1386 : // For references, the 'lvalue' is the pointer address stored in the
1387 : // reference region.
20: branch 3 taken
2494: branch 4 taken
1388 2514: if (VD->getType()->isReferenceType()) {
20: branch 1 taken
0: branch 2 not taken
1389 20: if (const MemRegion *R = V.getAsRegion())
1390 20: V = state->getSVal(R);
1391 : else
1392 0: V = UnknownVal();
1393 : }
1394 :
1395 : MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, V),
1396 2514: ProgramPoint::PostLValueKind);
1397 : }
1398 : else
1399 6031: EvalLoad(Dst, Ex, Pred, state, V);
1400 :
1401 8545: return;
118: branch 1 taken
1634: branch 2 taken
1402 1752: } else if (const EnumConstantDecl* ED = dyn_cast<EnumConstantDecl>(D)) {
0: branch 0 not taken
118: branch 1 taken
1403 118: assert(!asLValue && "EnumConstantDecl does not have lvalue.");
1404 :
1405 118: SVal V = ValMgr.makeIntVal(ED->getInitVal());
1406 118: MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, V));
1407 118: return;
1408 :
1634: branch 1 taken
0: branch 2 not taken
1409 1634: } else if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(D)) {
1410 : // This code is valid regardless of the value of 'isLValue'.
1411 1634: SVal V = ValMgr.getFunctionPointer(FD);
1412 : MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, V),
1413 1634: ProgramPoint::PostLValueKind);
1414 1634: return;
1415 : }
1416 :
1417 : assert (false &&
1418 0: "ValueDecl support for this ValueDecl not implemented.");
1419 : }
1420 :
1421 : /// VisitArraySubscriptExpr - Transfer function for array accesses
1422 : void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A,
1423 : ExplodedNode* Pred,
1424 455: ExplodedNodeSet& Dst, bool asLValue){
1425 :
1426 455: Expr* Base = A->getBase()->IgnoreParens();
1427 455: Expr* Idx = A->getIdx()->IgnoreParens();
1428 455: ExplodedNodeSet Tmp;
1429 :
10: branch 3 taken
445: branch 4 taken
1430 455: if (Base->getType()->isVectorType()) {
1431 : // For vector types get its lvalue.
1432 : // FIXME: This may not be correct. Is the rvalue of a vector its location?
1433 : // In fact, I think this is just a hack. We need to get the right
1434 : // semantics.
1435 10: VisitLValue(Base, Pred, Tmp);
1436 : }
1437 : else
1438 445: Visit(Base, Pred, Tmp); // Get Base's rvalue, which should be an LocVal.
1439 :
455: branch 6 taken
455: branch 7 taken
1440 910: for (ExplodedNodeSet::iterator I1=Tmp.begin(), E1=Tmp.end(); I1!=E1; ++I1) {
1441 455: ExplodedNodeSet Tmp2;
1442 455: Visit(Idx, *I1, Tmp2); // Evaluate the index.
1443 :
1444 455: ExplodedNodeSet Tmp3;
1445 455: CheckerVisit(A, Tmp3, Tmp2, true);
1446 :
445: branch 5 taken
455: branch 6 taken
1447 900: for (ExplodedNodeSet::iterator I2=Tmp3.begin(),E2=Tmp3.end();I2!=E2; ++I2) {
1448 445: const GRState* state = GetState(*I2);
1449 : SVal V = state->getLValue(A->getType(), state->getSVal(Idx),
1450 445: state->getSVal(Base));
1451 :
210: branch 0 taken
235: branch 1 taken
1452 445: if (asLValue)
1453 : MakeNode(Dst, A, *I2, state->BindExpr(A, V),
1454 210: ProgramPoint::PostLValueKind);
1455 : else
1456 235: EvalLoad(Dst, A, *I2, state, V);
1457 : }
1458 455: }
1459 455: }
1460 :
1461 : /// VisitMemberExpr - Transfer function for member expressions.
1462 : void GRExprEngine::VisitMemberExpr(MemberExpr* M, ExplodedNode* Pred,
1463 378: ExplodedNodeSet& Dst, bool asLValue) {
1464 :
1465 378: Expr* Base = M->getBase()->IgnoreParens();
1466 378: ExplodedNodeSet Tmp;
1467 :
154: branch 1 taken
224: branch 2 taken
1468 378: if (M->isArrow())
1469 154: Visit(Base, Pred, Tmp); // p->f = ... or ... = p->f
1470 : else
1471 224: VisitLValue(Base, Pred, Tmp); // x.f = ... or ... = x.f
1472 :
1473 378: FieldDecl *Field = dyn_cast<FieldDecl>(M->getMemberDecl());
0: branch 0 not taken
378: branch 1 taken
1474 378: if (!Field) // FIXME: skipping member expressions for non-fields
1475 0: return;
1476 :
378: branch 5 taken
378: branch 6 taken
1477 756: for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) {
1478 378: const GRState* state = GetState(*I);
1479 : // FIXME: Should we insert some assumption logic in here to determine
1480 : // if "Base" is a valid piece of memory? Before we put this assumption
1481 : // later when using FieldOffset lvals (which we no longer have).
1482 378: SVal L = state->getLValue(Field, state->getSVal(Base));
1483 :
214: branch 0 taken
164: branch 1 taken
1484 378: if (asLValue)
1485 214: MakeNode(Dst, M, *I, state->BindExpr(M, L), ProgramPoint::PostLValueKind);
1486 : else
1487 164: EvalLoad(Dst, M, *I, state, L);
378: branch 1 taken
0: branch 2 not taken
1488 378: }
1489 : }
1490 :
1491 : /// EvalBind - Handle the semantics of binding a value to a specific location.
1492 : /// This method is used by EvalStore and (soon) VisitDeclStmt, and others.
1493 : void GRExprEngine::EvalBind(ExplodedNodeSet& Dst, Stmt *AssignE,
1494 : Stmt* StoreE, ExplodedNode* Pred,
1495 : const GRState* state, SVal location, SVal Val,
1496 3974: bool atDeclInit) {
1497 :
1498 :
1499 : // Do a previsit of the bind.
1500 3974: ExplodedNodeSet CheckedSet, Src;
1501 3974: Src.Add(Pred);
1502 3974: CheckerVisitBind(AssignE, StoreE, CheckedSet, Src, location, Val, true);
1503 :
3973: branch 5 taken
3974: branch 6 taken
1504 7947: for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
1505 : I!=E; ++I) {
1506 :
0: branch 1 not taken
3973: branch 2 taken
1507 3973: if (Pred != *I)
1508 0: state = GetState(*I);
1509 :
1510 3973: const GRState* newState = 0;
1511 :
1743: branch 0 taken
2230: branch 1 taken
1512 3973: if (atDeclInit) {
1513 : const VarRegion *VR =
1514 1743: cast<VarRegion>(cast<loc::MemRegionVal>(location).getRegion());
1515 :
1516 1743: newState = state->bindDecl(VR, Val);
1517 : }
1518 : else {
48: branch 1 taken
2182: branch 2 taken
1519 2230: if (location.isUnknown()) {
1520 : // We know that the new state will be the same as the old state since
1521 : // the location of the binding is "unknown". Consequently, there
1522 : // is no reason to just create a new node.
1523 48: newState = state;
1524 : }
1525 : else {
1526 : // We are binding to a value other than 'unknown'. Perform the binding
1527 : // using the StoreManager.
1528 2182: newState = state->bindLoc(cast<Loc>(location), Val);
1529 : }
1530 : }
1531 :
1532 : // The next thing to do is check if the GRTransferFuncs object wants to
1533 : // update the state based on the new binding. If the GRTransferFunc object
1534 : // doesn't do anything, just auto-propagate the current state.
1535 : GRStmtNodeBuilderRef BuilderRef(Dst, *Builder, *this, *I, newState, StoreE,
1536 3973: newState != state);
1537 :
1538 3973: getTF().EvalBind(BuilderRef, location, Val);
1539 3974: }
1540 3974: }
1541 :
1542 : /// EvalStore - Handle the semantics of a store via an assignment.
1543 : /// @param Dst The node set to store generated state nodes
1544 : /// @param Ex The expression representing the location of the store
1545 : /// @param state The current simulation state
1546 : /// @param location The location to store the value
1547 : /// @param Val The value to be stored
1548 : void GRExprEngine::EvalStore(ExplodedNodeSet& Dst, Expr *AssignE,
1549 : Expr* StoreE,
1550 : ExplodedNode* Pred,
1551 : const GRState* state, SVal location, SVal Val,
1552 2295: const void *tag) {
1553 :
0: branch 0 not taken
2295: branch 1 taken
1554 2295: assert(Builder && "GRStmtNodeBuilder must be defined.");
1555 :
1556 : // Evaluate the location (checks for bad dereferences).
1557 2295: ExplodedNodeSet Tmp;
1558 2295: EvalLocation(Tmp, StoreE, Pred, state, location, tag, false);
1559 :
64: branch 1 taken
2231: branch 2 taken
1560 2295: if (Tmp.empty())
1561 64: return;
1562 :
0: branch 1 not taken
2231: branch 2 taken
1563 2231: assert(!location.isUndef());
1564 :
1565 : SaveAndRestore<ProgramPoint::Kind> OldSPointKind(Builder->PointKind,
1566 2231: ProgramPoint::PostStoreKind);
1567 2231: SaveAndRestore<const void*> OldTag(Builder->Tag, tag);
1568 :
1569 : // Proceed with the store.
2231: branch 4 taken
2231: branch 5 taken
1570 4462: for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI)
2231: branch 9 taken
64: branch 10 taken
1571 4462: EvalBind(Dst, AssignE, StoreE, *NI, GetState(*NI), location, Val);
1572 : }
1573 :
1574 : void GRExprEngine::EvalLoad(ExplodedNodeSet& Dst, Expr *Ex, ExplodedNode* Pred,
1575 : const GRState* state, SVal location,
1576 7966: const void *tag, QualType LoadTy) {
1577 :
1578 : // Are we loading from a region? This actually results in two loads; one
1579 : // to fetch the address of the referenced value and one to fetch the
1580 : // referenced value.
7717: branch 0 taken
249: branch 1 taken
1581 7966: if (const TypedRegion *TR =
1582 7966: dyn_cast_or_null<TypedRegion>(location.getAsRegion())) {
1583 :
1584 7717: QualType ValTy = TR->getValueType(getContext());
1: branch 2 taken
7716: branch 3 taken
1585 7717: if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) {
1586 : static int loadReferenceTag = 0;
1587 1: ExplodedNodeSet Tmp;
1588 : EvalLoadCommon(Tmp, Ex, Pred, state, location, &loadReferenceTag,
1589 1: getContext().getPointerType(RT->getPointeeType()));
1590 :
1591 : // Perform the load from the referenced value.
1: branch 4 taken
1: branch 5 taken
1592 2: for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end() ; I!=E; ++I) {
1593 1: state = GetState(*I);
1594 1: location = state->getSVal(Ex);
1595 1: EvalLoadCommon(Dst, Ex, *I, state, location, tag, LoadTy);
1596 : }
1597 1: return;
1598 : }
1599 : }
1600 :
1601 7965: EvalLoadCommon(Dst, Ex, Pred, state, location, tag, LoadTy);
1602 : }
1603 :
1604 : void GRExprEngine::EvalLoadCommon(ExplodedNodeSet& Dst, Expr *Ex,
1605 : ExplodedNode* Pred,
1606 : const GRState* state, SVal location,
1607 7967: const void *tag, QualType LoadTy) {
1608 :
1609 : // Evaluate the location (checks for bad dereferences).
1610 7967: ExplodedNodeSet Tmp;
1611 7967: EvalLocation(Tmp, Ex, Pred, state, location, tag, true);
1612 :
25: branch 1 taken
7942: branch 2 taken
1613 7967: if (Tmp.empty())
1614 25: return;
1615 :
0: branch 1 not taken
7942: branch 2 taken
1616 7942: assert(!location.isUndef());
1617 :
1618 7942: SaveAndRestore<ProgramPoint::Kind> OldSPointKind(Builder->PointKind);
1619 7942: SaveAndRestore<const void*> OldTag(Builder->Tag);
1620 :
1621 : // Proceed with the load.
7942: branch 4 taken
7942: branch 5 taken
1622 15884: for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) {
1623 7942: state = GetState(*NI);
75: branch 1 taken
7867: branch 2 taken
1624 7942: if (location.isUnknown()) {
1625 : // This is important. We must nuke the old binding.
1626 : MakeNode(Dst, Ex, *NI, state->BindExpr(Ex, UnknownVal()),
1627 75: ProgramPoint::PostLoadKind, tag);
1628 : }
1629 : else {
1630 : SVal V = state->getSVal(cast<Loc>(location), LoadTy.isNull() ?
7788: branch 1 taken
79: branch 2 taken
1631 7867: Ex->getType() : LoadTy);
1632 : MakeNode(Dst, Ex, *NI, state->BindExpr(Ex, V), ProgramPoint::PostLoadKind,
1633 7867: tag);
1634 : }
7942: branch 3 taken
25: branch 4 taken
1635 7942: }
1636 : }
1637 :
1638 : void GRExprEngine::EvalLocation(ExplodedNodeSet &Dst, Stmt *S,
1639 : ExplodedNode* Pred,
1640 : const GRState* state, SVal location,
1641 10282: const void *tag, bool isLoad) {
1642 : // Early checks for performance reason.
10159: branch 1 taken
123: branch 2 taken
0: branch 4 not taken
10159: branch 5 taken
123: branch 6 taken
10159: branch 7 taken
1643 10282: if (location.isUnknown() || Checkers.empty()) {
1644 123: Dst.Add(Pred);
1645 123: return;
1646 : }
1647 :
1648 10159: ExplodedNodeSet Src, Tmp;
1649 10159: Src.Add(Pred);
1650 10159: ExplodedNodeSet *PrevSet = &Src;
1651 :
229791: branch 4 taken
10159: branch 5 taken
1652 239950: for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end(); I!=E; ++I)
1653 : {
1654 229791: ExplodedNodeSet *CurrSet = 0;
10159: branch 2 taken
219632: branch 3 taken
1655 229791: if (I+1 == E)
1656 10159: CurrSet = &Dst;
1657 : else {
108628: branch 0 taken
111004: branch 1 taken
1658 219632: CurrSet = (PrevSet == &Tmp) ? &Src : &Tmp;
1659 219632: CurrSet->clear();
1660 : }
1661 :
1662 229791: void *tag = I->first;
1663 229791: Checker *checker = I->second;
1664 :
228204: branch 4 taken
229791: branch 5 taken
1665 457995: for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
1666 : NI != NE; ++NI) {
1667 : // Use the 'state' argument only when the predecessor node is the
1668 : // same as Pred. This allows us to catch updates to the state.
1669 : checker->GR_VisitLocation(*CurrSet, *Builder, *this, S, *NI,
1670 : *NI == Pred ? state : GetState(*NI),
50170: branch 1 taken
178034: branch 2 taken
1671 228204: location, tag, isLoad);
1672 : }
1673 :
1674 : // Update which NodeSet is the current one.
1675 229791: PrevSet = CurrSet;
1676 10159: }
1677 : }
1678 :
1679 : //===----------------------------------------------------------------------===//
1680 : // Transfer function: Function calls.
1681 : //===----------------------------------------------------------------------===//
1682 :
1683 : namespace {
1684 3923: class CallExprWLItem {
1685 : public:
1686 : CallExpr::arg_iterator I;
1687 : ExplodedNode *N;
1688 :
1689 3923: CallExprWLItem(const CallExpr::arg_iterator &i, ExplodedNode *n)
1690 3923: : I(i), N(n) {}
1691 : };
1692 : } // end anonymous namespace
1693 :
1694 : void GRExprEngine::VisitCall(CallExpr* CE, ExplodedNode* Pred,
1695 : CallExpr::arg_iterator AI,
1696 : CallExpr::arg_iterator AE,
1697 1689: ExplodedNodeSet& Dst, bool asLValue) {
1698 :
1699 : // Determine the type of function we're calling (if available).
1700 1689: const FunctionProtoType *Proto = NULL;
1701 1689: QualType FnType = CE->getCallee()->IgnoreParens()->getType();
1637: branch 2 taken
52: branch 3 taken
1702 1689: if (const PointerType *FnTypePtr = FnType->getAs<PointerType>())
1703 1637: Proto = FnTypePtr->getPointeeType()->getAs<FunctionProtoType>();
1704 :
1705 : // Create a worklist to process the arguments.
1706 1689: llvm::SmallVector<CallExprWLItem, 20> WorkList;
1707 1689: WorkList.reserve(AE - AI);
1708 1689: WorkList.push_back(CallExprWLItem(AI, Pred));
1709 :
1710 1689: ExplodedNodeSet ArgsEvaluated;
1711 :
3923: branch 2 taken
1689: branch 3 taken
1712 3934: while (!WorkList.empty()) {
1713 3923: CallExprWLItem Item = WorkList.back();
1714 3923: WorkList.pop_back();
1715 :
1678: branch 1 taken
2245: branch 2 taken
1716 3923: if (Item.I == AE) {
1717 1678: ArgsEvaluated.insert(Item.N);
1718 1678: continue;
1719 : }
1720 :
1721 : // Evaluate the argument.
1722 2245: ExplodedNodeSet Tmp;
1723 2245: const unsigned ParamIdx = Item.I - AI;
1724 :
1725 2245: bool VisitAsLvalue = false;
2131: branch 0 taken
114: branch 1 taken
2004: branch 3 taken
127: branch 4 taken
2004: branch 5 taken
241: branch 6 taken
1726 2245: if (Proto && ParamIdx < Proto->getNumArgs())
1727 2004: VisitAsLvalue = Proto->getArgType(ParamIdx)->isReferenceType();
1728 :
14: branch 0 taken
2231: branch 1 taken
1729 2245: if (VisitAsLvalue)
1730 14: VisitLValue(*Item.I, Item.N, Tmp);
1731 : else
1732 2231: Visit(*Item.I, Item.N, Tmp);
1733 :
1734 : // Enqueue evaluating the next argument on the worklist.
1735 2245: ++(Item.I);
1736 :
2234: branch 4 taken
2245: branch 5 taken
1737 4479: for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI)
1738 2234: WorkList.push_back(CallExprWLItem(Item.I, *NI));
1739 : }
1740 :
1741 : // Now process the call itself.
1742 1689: ExplodedNodeSet DstTmp;
1743 1689: Expr* Callee = CE->getCallee()->IgnoreParens();
1744 :
1678: branch 4 taken
1689: branch 5 taken
1745 5056: for (ExplodedNodeSet::iterator NI=ArgsEvaluated.begin(),
1746 1689: NE=ArgsEvaluated.end(); NI != NE; ++NI) {
1747 : // Evaluate the callee.
1748 1678: ExplodedNodeSet DstTmp2;
1749 1678: Visit(Callee, *NI, DstTmp2);
1750 : // Perform the previsit of the CallExpr, storing the results in DstTmp.
1751 1678: CheckerVisit(CE, DstTmp, DstTmp2, true);
1752 : }
1753 :
1754 : // Finally, evaluate the function call. We try each of the checkers
1755 : // to see if the can evaluate the function call.
1756 1689: ExplodedNodeSet DstTmp3;
1757 :
1758 :
1646: branch 7 taken
1689: branch 8 taken
1759 3335: for (ExplodedNodeSet::iterator DI = DstTmp.begin(), DE = DstTmp.end();
1760 : DI != DE; ++DI) {
1761 :
1762 1646: const GRState* state = GetState(*DI);
1763 1646: SVal L = state->getSVal(Callee);
1764 :
1765 : // FIXME: Add support for symbolic function calls (calls involving
1766 : // function pointer values that are symbolic).
1767 1646: SaveAndRestore<bool> OldSink(Builder->BuildSinks);
1768 1646: ExplodedNodeSet DstChecker;
1769 :
1770 : // If the callee is processed by a checker, skip the rest logic.
126: branch 2 taken
1520: branch 3 taken
1771 1646: if (CheckerEvalCall(CE, DstChecker, *DI))
1772 126: DstTmp3.insert(DstChecker);
1773 : else {
1520: branch 4 taken
1520: branch 5 taken
1774 4560: for (ExplodedNodeSet::iterator DI_Checker = DstChecker.begin(),
1775 1520: DE_Checker = DstChecker.end();
1776 : DI_Checker != DE_Checker; ++DI_Checker) {
1777 :
1778 : // Dispatch to the plug-in transfer function.
1779 1520: unsigned OldSize = DstTmp3.size();
1780 1520: SaveOr OldHasGen(Builder->HasGeneratedNode);
1781 1520: Pred = *DI_Checker;
1782 :
1783 : // Dispatch to transfer function logic to handle the call itself.
1784 : // FIXME: Allow us to chain together transfer functions.
0: branch 0 not taken
1520: branch 1 taken
1785 1520: assert(Builder && "GRStmtNodeBuilder must be defined.");
1786 1520: getTF().EvalCall(DstTmp3, *this, *Builder, CE, L, Pred);
1787 :
1788 : // Handle the case where no nodes where generated. Auto-generate that
1789 : // contains the updated state if we aren't generating sinks.
1491: branch 0 taken
29: branch 1 taken
12: branch 3 taken
1479: branch 4 taken
0: branch 5 not taken
12: branch 6 taken
0: branch 7 not taken
1520: branch 8 taken
1790 1520: if (!Builder->BuildSinks && DstTmp3.size() == OldSize &&
1791 : !Builder->HasGeneratedNode)
1792 0: MakeNode(DstTmp3, CE, Pred, state);
1793 : }
1794 : }
1795 : }
1796 :
1797 : // Finally, perform the post-condition check of the CallExpr and store
1798 : // the created nodes in 'Dst'.
1799 :
1683: branch 0 taken
6: branch 1 taken
1679: branch 3 taken
4: branch 4 taken
1685: branch 5 taken
4: branch 6 taken
1800 1689: if (!(!asLValue && CalleeReturnsReference(CE))) {
1801 1685: CheckerVisit(CE, Dst, DstTmp3, false);
1802 1685: return;
1803 : }
1804 :
1805 : // Handle the case where the called function returns a reference but
1806 : // we expect an rvalue. For such cases, convert the reference to
1807 : // an rvalue.
1808 : // FIXME: This conversion doesn't actually happen unless the result
1809 : // of CallExpr is consumed by another expression.
1810 4: ExplodedNodeSet DstTmp4;
1811 4: CheckerVisit(CE, DstTmp4, DstTmp3, false);
1812 4: QualType LoadTy = CE->getType();
1813 :
1814 : static int *ConvertToRvalueTag = 0;
4: branch 4 taken
4: branch 5 taken
1815 8: for (ExplodedNodeSet::iterator NI = DstTmp4.begin(), NE = DstTmp4.end();
1816 : NI!=NE; ++NI) {
1817 4: const GRState *state = GetState(*NI);
1818 : EvalLoad(Dst, CE, *NI, state, state->getSVal(CE),
1819 4: &ConvertToRvalueTag, LoadTy);
4: branch 2 taken
1685: branch 3 taken
4: branch 5 taken
1685: branch 6 taken
4: branch 8 taken
1685: branch 9 taken
4: branch 11 taken
1685: branch 12 taken
1820 4: }
1821 : }
1822 :
1823 : //===----------------------------------------------------------------------===//
1824 : // Transfer function: Objective-C ivar references.
1825 : //===----------------------------------------------------------------------===//
1826 :
1827 : static std::pair<const void*,const void*> EagerlyAssumeTag
1828 2753: = std::pair<const void*,const void*>(&EagerlyAssumeTag,0);
1829 :
1830 : void GRExprEngine::EvalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
1831 20: Expr *Ex) {
26: branch 5 taken
20: branch 6 taken
1832 46: for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) {
1833 26: ExplodedNode *Pred = *I;
1834 :
1835 : // Test if the previous node was as the same expression. This can happen
1836 : // when the expression fails to evaluate to anything meaningful and
1837 : // (as an optimization) we don't generate a node.
1838 26: ProgramPoint P = Pred->getLocation();
26: branch 1 taken
0: branch 2 not taken
0: branch 5 not taken
26: branch 6 taken
0: branch 7 not taken
26: branch 8 taken
1839 26: if (!isa<PostStmt>(P) || cast<PostStmt>(P).getStmt() != Ex) {
1840 0: Dst.Add(Pred);
1841 0: continue;
1842 : }
1843 :
1844 26: const GRState* state = Pred->getState();
1845 26: SVal V = state->getSVal(Ex);
9: branch 1 taken
17: branch 2 taken
1846 26: if (nonloc::SymExprVal *SEV = dyn_cast<nonloc::SymExprVal>(&V)) {
1847 : // First assume that the condition is true.
8: branch 2 taken
1: branch 3 taken
1848 9: if (const GRState *stateTrue = state->Assume(*SEV, true)) {
1849 : stateTrue = stateTrue->BindExpr(Ex,
1850 8: ValMgr.makeIntVal(1U, Ex->getType()));
1851 : Dst.Add(Builder->generateNode(PostStmtCustom(Ex,
1852 : &EagerlyAssumeTag, Pred->getLocationContext()),
1853 8: stateTrue, Pred));
1854 : }
1855 :
1856 : // Next, assume that the condition is false.
6: branch 2 taken
3: branch 3 taken
1857 9: if (const GRState *stateFalse = state->Assume(*SEV, false)) {
1858 : stateFalse = stateFalse->BindExpr(Ex,
1859 6: ValMgr.makeIntVal(0U, Ex->getType()));
1860 : Dst.Add(Builder->generateNode(PostStmtCustom(Ex, &EagerlyAssumeTag,
1861 : Pred->getLocationContext()),
1862 6: stateFalse, Pred));
1863 : }
1864 : }
1865 : else
1866 17: Dst.Add(Pred);
1867 : }
1868 20: }
1869 :
1870 : //===----------------------------------------------------------------------===//
1871 : // Transfer function: Objective-C ivar references.
1872 : //===----------------------------------------------------------------------===//
1873 :
1874 : void GRExprEngine::VisitObjCIvarRefExpr(ObjCIvarRefExpr* Ex, ExplodedNode* Pred,
1875 155: ExplodedNodeSet& Dst, bool asLValue) {
1876 :
1877 155: Expr* Base = cast<Expr>(Ex->getBase());
1878 155: ExplodedNodeSet Tmp;
1879 155: Visit(Base, Pred, Tmp);
1880 :
149: branch 6 taken
155: branch 7 taken
1881 304: for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
1882 149: const GRState* state = GetState(*I);
1883 149: SVal BaseVal = state->getSVal(Base);
1884 149: SVal location = state->getLValue(Ex->getDecl(), BaseVal);
1885 :
43: branch 0 taken
106: branch 1 taken
1886 149: if (asLValue)
1887 43: MakeNode(Dst, Ex, *I, state->BindExpr(Ex, location));
1888 : else
1889 106: EvalLoad(Dst, Ex, *I, state, location);
1890 155: }
1891 155: }
1892 :
1893 : //===----------------------------------------------------------------------===//
1894 : // Transfer function: Objective-C fast enumeration 'for' statements.
1895 : //===----------------------------------------------------------------------===//
1896 :
1897 : void GRExprEngine::VisitObjCForCollectionStmt(ObjCForCollectionStmt* S,
1898 20: ExplodedNode* Pred, ExplodedNodeSet& Dst) {
1899 :
1900 : // ObjCForCollectionStmts are processed in two places. This method
1901 : // handles the case where an ObjCForCollectionStmt* occurs as one of the
1902 : // statements within a basic block. This transfer function does two things:
1903 : //
1904 : // (1) binds the next container value to 'element'. This creates a new
1905 : // node in the ExplodedGraph.
1906 : //
1907 : // (2) binds the value 0/1 to the ObjCForCollectionStmt* itself, indicating
1908 : // whether or not the container has any more elements. This value
1909 : // will be tested in ProcessBranch. We need to explicitly bind
1910 : // this value because a container can contain nil elements.
1911 : //
1912 : // FIXME: Eventually this logic should actually do dispatches to
1913 : // 'countByEnumeratingWithState:objects:count:' (NSFastEnumeration).
1914 : // This will require simulating a temporary NSFastEnumerationState, either
1915 : // through an SVal or through the use of MemRegions. This value can
1916 : // be affixed to the ObjCForCollectionStmt* instead of 0/1; when the loop
1917 : // terminates we reclaim the temporary (it goes out of scope) and we
1918 : // we can test if the SVal is 0 or if the MemRegion is null (depending
1919 : // on what approach we take).
1920 : //
1921 : // For now: simulate (1) by assigning either a symbol or nil if the
1922 : // container is empty. Thus this transfer function will by default
1923 : // result in state splitting.
1924 :
1925 20: Stmt* elem = S->getElement();
1926 20: SVal ElementV;
1927 :
0: branch 1 not taken
20: branch 2 taken
1928 20: if (DeclStmt* DS = dyn_cast<DeclStmt>(elem)) {
1929 0: VarDecl* ElemD = cast<VarDecl>(DS->getSingleDecl());
0: branch 1 not taken
0: branch 2 not taken
1930 0: assert (ElemD->getInit() == 0);
1931 0: ElementV = GetState(Pred)->getLValue(ElemD, Pred->getLocationContext());
1932 0: VisitObjCForCollectionStmtAux(S, Pred, Dst, ElementV);
1933 0: return;
1934 : }
1935 :
1936 20: ExplodedNodeSet Tmp;
1937 20: VisitLValue(cast<Expr>(elem), Pred, Tmp);
1938 :
20: branch 4 taken
20: branch 5 taken
1939 40: for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) {
1940 20: const GRState* state = GetState(*I);
1941 20: VisitObjCForCollectionStmtAux(S, *I, Dst, state->getSVal(elem));
20: branch 2 taken
0: branch 3 not taken
1942 20: }
1943 : }
1944 :
1945 : void GRExprEngine::VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S,
1946 : ExplodedNode* Pred, ExplodedNodeSet& Dst,
1947 20: SVal ElementV) {
1948 :
1949 : // Check if the location we are writing back to is a null pointer.
1950 20: Stmt* elem = S->getElement();
1951 20: ExplodedNodeSet Tmp;
1952 20: EvalLocation(Tmp, elem, Pred, GetState(Pred), ElementV, NULL, false);
1953 :
0: branch 1 not taken
20: branch 2 taken
1954 20: if (Tmp.empty())
1955 0: return;
1956 :
20: branch 6 taken
20: branch 7 taken
1957 40: for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) {
1958 20: Pred = *NI;
1959 20: const GRState *state = GetState(Pred);
1960 :
1961 : // Handle the case where the container still has elements.
1962 20: SVal TrueV = ValMgr.makeTruthVal(1);
1963 20: const GRState *hasElems = state->BindExpr(S, TrueV);
1964 :
1965 : // Handle the case where the container has no elements.
1966 20: SVal FalseV = ValMgr.makeTruthVal(0);
1967 20: const GRState *noElems = state->BindExpr(S, FalseV);
1968 :
20: branch 1 taken
0: branch 2 not taken
1969 20: if (loc::MemRegionVal* MV = dyn_cast<loc::MemRegionVal>(&ElementV))
20: branch 2 taken
0: branch 3 not taken
1970 20: if (const TypedRegion* R = dyn_cast<TypedRegion>(MV->getRegion())) {
1971 : // FIXME: The proper thing to do is to really iterate over the
1972 : // container. We will do this with dispatch logic to the store.
1973 : // For now, just 'conjure' up a symbolic value.
1974 20: QualType T = R->getValueType(getContext());
0: branch 1 not taken
20: branch 2 taken
1975 20: assert(Loc::IsLocType(T));
1976 20: unsigned Count = Builder->getCurrentBlockCount();
1977 20: SymbolRef Sym = SymMgr.getConjuredSymbol(elem, T, Count);
1978 20: SVal V = ValMgr.makeLoc(Sym);
1979 20: hasElems = hasElems->bindLoc(ElementV, V);
1980 :
1981 : // Bind the location to 'nil' on the false branch.
1982 20: SVal nilV = ValMgr.makeIntVal(0, T);
1983 20: noElems = noElems->bindLoc(ElementV, nilV);
1984 : }
1985 :
1986 : // Create the new nodes.
1987 20: MakeNode(Dst, S, Pred, hasElems);
1988 20: MakeNode(Dst, S, Pred, noElems);
20: branch 1 taken
0: branch 2 not taken
1989 20: }
1990 : }
1991 :
1992 : //===----------------------------------------------------------------------===//
1993 : // Transfer function: Objective-C message expressions.
1994 : //===----------------------------------------------------------------------===//
1995 :
1996 : void GRExprEngine::VisitObjCMessageExpr(ObjCMessageExpr* ME, ExplodedNode* Pred,
1997 1271: ExplodedNodeSet& Dst, bool asLValue){
1998 :
1999 : VisitObjCMessageExprArgHelper(ME, ME->arg_begin(), ME->arg_end(),
2000 1271: Pred, Dst, asLValue);
2001 1271: }
2002 :
2003 : void GRExprEngine::VisitObjCMessageExprArgHelper(ObjCMessageExpr* ME,
2004 : ObjCMessageExpr::arg_iterator AI,
2005 : ObjCMessageExpr::arg_iterator AE,
2006 : ExplodedNode* Pred,
2007 : ExplodedNodeSet& Dst,
2008 1868: bool asLValue) {
1271: branch 1 taken
597: branch 2 taken
2009 1868: if (AI == AE) {
2010 :
2011 : // Process the receiver.
2012 :
906: branch 1 taken
365: branch 2 taken
2013 1271: if (Expr* Receiver = ME->getReceiver()) {
2014 906: ExplodedNodeSet Tmp;
2015 906: Visit(Receiver, Pred, Tmp);
2016 :
906: branch 4 taken
906: branch 5 taken
2017 1812: for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE;
2018 : ++NI)
2019 906: VisitObjCMessageExprDispatchHelper(ME, *NI, Dst, asLValue);
2020 :
2021 906: return;
2022 : }
2023 :
2024 365: VisitObjCMessageExprDispatchHelper(ME, Pred, Dst, asLValue);
2025 365: return;
2026 : }
2027 :
2028 597: ExplodedNodeSet Tmp;
2029 597: Visit(*AI, Pred, Tmp);
2030 :
2031 597: ++AI;
2032 :
597: branch 4 taken
597: branch 5 taken
2033 1194: for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end();NI != NE;++NI)
2034 1194: VisitObjCMessageExprArgHelper(ME, AI, AE, *NI, Dst, asLValue);
2035 : }
2036 :
2037 : void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME,
2038 : ExplodedNode* Pred,
2039 : ExplodedNodeSet& Dst,
2040 1271: bool asLValue) {
2041 :
2042 : // Handle previsits checks.
2043 1271: ExplodedNodeSet Src, DstTmp;
2044 1271: Src.Add(Pred);
2045 :
2046 1271: CheckerVisit(ME, DstTmp, Src, true);
2047 :
2048 1271: ExplodedNodeSet PostVisitSrc;
2049 :
1211: branch 3 taken
44: branch 4 taken
1211: branch 6 taken
44: branch 7 taken
1255: branch 10 taken
1271: branch 11 taken
2050 3781: for (ExplodedNodeSet::iterator DI = DstTmp.begin(), DE = DstTmp.end();
2051 : DI!=DE; ++DI) {
2052 :
2053 1255: Pred = *DI;
2054 1255: bool RaisesException = false;
2055 :
2056 1255: unsigned OldSize = PostVisitSrc.size();
2057 1255: SaveAndRestore<bool> OldSink(Builder->BuildSinks);
2058 1255: SaveOr OldHasGen(Builder->HasGeneratedNode);
2059 :
890: branch 1 taken
365: branch 2 taken
2060 1255: if (const Expr *Receiver = ME->getReceiver()) {
2061 890: const GRState *state = Pred->getState();
2062 :
2063 : // Bifurcate the state into nil and non-nil ones.
2064 : DefinedOrUnknownSVal receiverVal =
2065 890: cast<DefinedOrUnknownSVal>(state->getSVal(Receiver));
2066 :
2067 : const GRState *notNilState, *nilState;
2068 890: llvm::tie(notNilState, nilState) = state->Assume(receiverVal);
2069 :
2070 : // There are three cases: can be nil or non-nil, must be nil, must be
2071 : // non-nil. We handle must be nil, and merge the rest two into non-nil.
734: branch 0 taken
156: branch 1 taken
44: branch 2 taken
690: branch 3 taken
2072 890: if (nilState && !notNilState) {
2073 44: CheckerEvalNilReceiver(ME, PostVisitSrc, nilState, Pred);
2074 44: continue;
2075 : }
2076 :
0: branch 0 not taken
846: branch 1 taken
2077 846: assert(notNilState);
2078 :
2079 : // Check if the "raise" message was sent.
8: branch 2 taken
838: branch 3 taken
2080 846: if (ME->getSelector() == RaiseSel)
2081 8: RaisesException = true;
2082 :
2083 : // Check if we raise an exception. For now treat these as sinks.
2084 : // Eventually we will want to handle exceptions properly.
8: branch 0 taken
838: branch 1 taken
2085 846: if (RaisesException)
2086 8: Builder->BuildSinks = true;
2087 :
2088 : // Dispatch to plug-in transfer function.
846: branch 2 taken
44: branch 3 taken
2089 846: EvalObjCMessageExpr(PostVisitSrc, ME, Pred, notNilState);
2090 : }
2091 : else {
2092 365: IdentifierInfo* ClsName = ME->getClassName();
2093 365: Selector S = ME->getSelector();
2094 :
2095 : // Check for special instance methods.
274: branch 0 taken
91: branch 1 taken
2096 365: if (!NSExceptionII) {
2097 274: ASTContext& Ctx = getContext();
2098 274: NSExceptionII = &Ctx.Idents.get("NSException");
2099 : }
2100 :
24: branch 0 taken
341: branch 1 taken
2101 365: if (ClsName == NSExceptionII) {
2102 : enum { NUM_RAISE_SELECTORS = 2 };
2103 :
2104 : // Lazily create a cache of the selectors.
12: branch 0 taken
12: branch 1 taken
2105 24: if (!NSExceptionInstanceRaiseSelectors) {
2106 12: ASTContext& Ctx = getContext();
24: branch 2 taken
12: branch 3 taken
2107 12: NSExceptionInstanceRaiseSelectors = new Selector[NUM_RAISE_SELECTORS];
2108 12: llvm::SmallVector<IdentifierInfo*, NUM_RAISE_SELECTORS> II;
2109 12: unsigned idx = 0;
2110 :
2111 : // raise:format:
2112 12: II.push_back(&Ctx.Idents.get("raise"));
2113 12: II.push_back(&Ctx.Idents.get("format"));
2114 : NSExceptionInstanceRaiseSelectors[idx++] =
2115 12: Ctx.Selectors.getSelector(II.size(), &II[0]);
2116 :
2117 : // raise:format::arguments:
2118 12: II.push_back(&Ctx.Idents.get("arguments"));
2119 : NSExceptionInstanceRaiseSelectors[idx++] =
2120 12: Ctx.Selectors.getSelector(II.size(), &II[0]);
2121 : }
2122 :
40: branch 0 taken
8: branch 1 taken
2123 48: for (unsigned i = 0; i < NUM_RAISE_SELECTORS; ++i)
16: branch 1 taken
24: branch 2 taken
2124 40: if (S == NSExceptionInstanceRaiseSelectors[i]) {
2125 16: RaisesException = true;
2126 16: break;
2127 : }
2128 : }
2129 :
2130 : // Check if we raise an exception. For now treat these as sinks.
2131 : // Eventually we will want to handle exceptions properly.
16: branch 0 taken
349: branch 1 taken
2132 365: if (RaisesException)
2133 16: Builder->BuildSinks = true;
2134 :
2135 : // Dispatch to plug-in transfer function.
2136 365: EvalObjCMessageExpr(PostVisitSrc, ME, Pred, Builder->GetState(Pred));
2137 : }
2138 :
2139 : // Handle the case where no nodes where generated. Auto-generate that
2140 : // contains the updated state if we aren't generating sinks.
1171: branch 0 taken
40: branch 1 taken
32: branch 3 taken
1139: branch 4 taken
0: branch 5 not taken
32: branch 6 taken
0: branch 7 not taken
1211: branch 8 taken
2141 1211: if (!Builder->BuildSinks && PostVisitSrc.size() == OldSize &&
2142 : !Builder->HasGeneratedNode)
2143 0: MakeNode(PostVisitSrc, ME, Pred, GetState(Pred));
2144 : }
2145 :
2146 : // Finally, perform the post-condition check of the ObjCMessageExpr and store
2147 : // the created nodes in 'Dst'.
1267: branch 0 taken
4: branch 1 taken
1265: branch 3 taken
2: branch 4 taken
1269: branch 5 taken
2: branch 6 taken
2148 1271: if (!(!asLValue && ReceiverReturnsReference(ME))) {
2149 1269: CheckerVisit(ME, Dst, PostVisitSrc, false);
2150 1269: return;
2151 : }
2152 :
2153 : // Handle the case where the message expression returns a reference but
2154 : // we expect an rvalue. For such cases, convert the reference to
2155 : // an rvalue.
2156 : // FIXME: This conversion doesn't actually happen unless the result
2157 : // of ObjCMessageExpr is consumed by another expression.
2158 2: ExplodedNodeSet DstRValueConvert;
2159 2: CheckerVisit(ME, DstRValueConvert, PostVisitSrc, false);
2160 2: QualType LoadTy = ME->getType();
2161 :
2162 : static int *ConvertToRvalueTag = 0;
2: branch 3 taken
2: branch 4 taken
2163 6: for (ExplodedNodeSet::iterator NI = DstRValueConvert.begin(),
2164 2: NE = DstRValueConvert.end();
2165 : NI!=NE; ++NI) {
2166 2: const GRState *state = GetState(*NI);
2167 : EvalLoad(Dst, ME, *NI, state, state->getSVal(ME),
2168 2: &ConvertToRvalueTag, LoadTy);
2: branch 2 taken
1269: branch 3 taken
2: branch 5 taken
1269: branch 6 taken
2: branch 8 taken
1269: branch 9 taken
2169 2: }
2170 : }
2171 :
2172 : //===----------------------------------------------------------------------===//
2173 : // Transfer functions: Miscellaneous statements.
2174 : //===----------------------------------------------------------------------===//
2175 :
2176 : void GRExprEngine::VisitCast(CastExpr *CastE, Expr *Ex, ExplodedNode *Pred,
2177 6804: ExplodedNodeSet &Dst, bool asLValue) {
2178 6804: ExplodedNodeSet S1;
2179 6804: QualType T = CastE->getType();
2180 6804: QualType ExTy = Ex->getType();
2181 :
1158: branch 1 taken
5646: branch 2 taken
2182 6804: if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
2183 1158: T = ExCast->getTypeAsWritten();
2184 :
6325: branch 2 taken
479: branch 3 taken
4675: branch 6 taken
1650: branch 7 taken
4675: branch 10 taken
0: branch 11 not taken
6: branch 12 taken
4669: branch 13 taken
2135: branch 14 taken
4669: branch 15 taken
2185 6804: if (ExTy->isArrayType() || ExTy->isFunctionType() || T->isReferenceType() ||
2186 : asLValue)
2187 2135: VisitLValue(Ex, Pred, S1);
2188 : else
2189 4669: Visit(Ex, Pred, S1);
2190 :
2191 6804: ExplodedNodeSet S2;
2192 6804: CheckerVisit(CastE, S2, S1, true);
2193 :
2194 : // If we are evaluating the cast in an lvalue context, we implicitly want
2195 : // the cast to evaluate to a location.
6: branch 0 taken
6798: branch 1 taken
2196 6804: if (asLValue) {
2197 6: ASTContext &Ctx = getContext();
2198 6: T = Ctx.getPointerType(Ctx.getCanonicalType(T));
2199 6: ExTy = Ctx.getPointerType(Ctx.getCanonicalType(ExTy));
2200 : }
2201 :
116: branch 1 taken
1864: branch 2 taken
4824: branch 3 taken
0: branch 4 not taken
2202 6804: switch (CastE->getCastKind()) {
2203 : case CastExpr::CK_ToVoid:
0: branch 0 not taken
116: branch 1 taken
2204 116: assert(!asLValue);
108: branch 4 taken
116: branch 5 taken
2205 224: for (ExplodedNodeSet::iterator I = S2.begin(), E = S2.end(); I != E; ++I)
2206 108: Dst.Add(*I);
2207 : return;
2208 :
2209 : case CastExpr::CK_NoOp:
2210 : case CastExpr::CK_FunctionToPointerDecay:
1858: branch 5 taken
1864: branch 6 taken
2211 3722: for (ExplodedNodeSet::iterator I = S2.begin(), E = S2.end(); I != E; ++I) {
2212 : // Copy the SVal of Ex to CastE.
2213 1858: ExplodedNode *N = *I;
2214 1858: const GRState *state = GetState(N);
2215 1858: SVal V = state->getSVal(Ex);
2216 1858: state = state->BindExpr(CastE, V);
2217 1858: MakeNode(Dst, CastE, N, state);
2218 : }
2219 : return;
2220 :
2221 : case CastExpr::CK_Unknown:
2222 : case CastExpr::CK_ArrayToPointerDecay:
2223 : case CastExpr::CK_BitCast:
2224 : case CastExpr::CK_IntegralCast:
2225 : case CastExpr::CK_IntegralToPointer:
2226 : case CastExpr::CK_PointerToIntegral:
2227 : case CastExpr::CK_IntegralToFloating:
2228 : case CastExpr::CK_FloatingToIntegral:
2229 : case CastExpr::CK_FloatingCast:
2230 : case CastExpr::CK_AnyPointerToObjCPointerCast:
2231 : case CastExpr::CK_AnyPointerToBlockPointerCast:
2232 : case CastExpr::CK_DerivedToBase:
2233 : // Delegate to SValuator to process.
4814: branch 5 taken
4824: branch 6 taken
2234 9638: for (ExplodedNodeSet::iterator I = S2.begin(), E = S2.end(); I != E; ++I) {
2235 4814: ExplodedNode* N = *I;
2236 4814: const GRState* state = GetState(N);
2237 4814: SVal V = state->getSVal(Ex);
2238 4814: V = SVator.EvalCast(V, T, ExTy);
2239 4814: state = state->BindExpr(CastE, V);
2240 4814: MakeNode(Dst, CastE, N, state);
2241 : }
2242 : return;
2243 :
2244 : default:
2245 0: llvm::errs() << "Cast kind " << CastE->getCastKind() << " not handled.\n";
2246 0: assert(0);
2247 6804: }
2248 : }
2249 :
2250 : void GRExprEngine::VisitCompoundLiteralExpr(CompoundLiteralExpr* CL,
2251 : ExplodedNode* Pred,
2252 : ExplodedNodeSet& Dst,
2253 39: bool asLValue) {
2254 39: InitListExpr* ILE = cast<InitListExpr>(CL->getInitializer()->IgnoreParens());
2255 39: ExplodedNodeSet Tmp;
2256 39: Visit(ILE, Pred, Tmp);
2257 :
39: branch 5 taken
39: branch 6 taken
2258 78: for (ExplodedNodeSet::iterator I = Tmp.begin(), EI = Tmp.end(); I!=EI; ++I) {
2259 39: const GRState* state = GetState(*I);
2260 39: SVal ILV = state->getSVal(ILE);
2261 39: const LocationContext *LC = (*I)->getLocationContext();
2262 39: state = state->bindCompoundLiteral(CL, LC, ILV);
2263 :
9: branch 0 taken
30: branch 1 taken
2264 39: if (asLValue) {
2265 9: MakeNode(Dst, CL, *I, state->BindExpr(CL, state->getLValue(CL, LC)));
2266 : }
2267 : else
2268 30: MakeNode(Dst, CL, *I, state->BindExpr(CL, ILV));
2269 39: }
2270 39: }
2271 :
2272 : void GRExprEngine::VisitDeclStmt(DeclStmt *DS, ExplodedNode *Pred,
2273 2604: ExplodedNodeSet& Dst) {
2274 :
2275 : // The CFG has one DeclStmt per Decl.
2276 2604: Decl* D = *DS->decl_begin();
2277 :
2604: branch 0 taken
0: branch 1 not taken
164: branch 3 taken
2440: branch 4 taken
164: branch 5 taken
2440: branch 6 taken
2278 2604: if (!D || !isa<VarDecl>(D))
2279 164: return;
2280 :
2281 2440: const VarDecl* VD = dyn_cast<VarDecl>(D);
2282 2440: Expr* InitEx = const_cast<Expr*>(VD->getInit());
2283 :
2284 : // FIXME: static variables may have an initializer, but the second
2285 : // time a function is called those values may not be current.
2286 2440: ExplodedNodeSet Tmp;
2287 :
1731: branch 0 taken
709: branch 1 taken
2288 2440: if (InitEx) {
13: branch 3 taken
1718: branch 4 taken
2289 1731: if (VD->getType()->isReferenceType())
2290 13: VisitLValue(InitEx, Pred, Tmp);
2291 : else
2292 1718: Visit(InitEx, Pred, Tmp);
2293 : }
2294 : else
2295 709: Tmp.Add(Pred);
2296 :
2297 2440: ExplodedNodeSet Tmp2;
2298 2440: CheckerVisit(DS, Tmp2, Tmp, true);
2299 :
2418: branch 4 taken
2440: branch 5 taken
2300 4858: for (ExplodedNodeSet::iterator I=Tmp2.begin(), E=Tmp2.end(); I!=E; ++I) {
2301 2418: ExplodedNode *N = *I;
2302 2418: const GRState *state = GetState(N);
2303 :
2304 : // Decls without InitExpr are not initialized explicitly.
2305 2418: const LocationContext *LC = N->getLocationContext();
2306 :
1729: branch 0 taken
689: branch 1 taken
2307 2418: if (InitEx) {
2308 1729: SVal InitVal = state->getSVal(InitEx);
2309 :
2310 : // Recover some path-sensitivity if a scalar value evaluated to
2311 : // UnknownVal.
1608: branch 1 taken
121: branch 2 taken
10: branch 5 taken
1598: branch 6 taken
1608: branch 7 taken
121: branch 8 taken
131: branch 10 taken
1598: branch 11 taken
2312 1729: if (InitVal.isUnknown() ||
2313 : !getConstraintManager().canReasonAbout(InitVal)) {
2314 : InitVal = ValMgr.getConjuredSymbolVal(NULL, InitEx,
2315 131: Builder->getCurrentBlockCount());
2316 : }
2317 :
2318 : EvalBind(Dst, DS, DS, *I, state,
2319 1729: loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true);
2320 : }
2321 : else {
2322 689: state = state->bindDeclWithNoInit(state->getRegion(VD, LC));
2323 689: MakeNode(Dst, DS, *I, state);
2324 : }
2325 2440: }
2326 : }
2327 :
2328 : void GRExprEngine::VisitCondInit(VarDecl *VD, Stmt *S,
2329 14: ExplodedNode *Pred, ExplodedNodeSet& Dst) {
2330 :
2331 14: Expr* InitEx = VD->getInit();
2332 14: ExplodedNodeSet Tmp;
2333 14: Visit(InitEx, Pred, Tmp);
2334 :
14: branch 5 taken
14: branch 6 taken
2335 28: for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
2336 14: ExplodedNode *N = *I;
2337 14: const GRState *state = GetState(N);
2338 :
2339 14: const LocationContext *LC = N->getLocationContext();
2340 14: SVal InitVal = state->getSVal(InitEx);
2341 :
2342 : // Recover some path-sensitivity if a scalar value evaluated to
2343 : // UnknownVal.
14: branch 1 taken
0: branch 2 not taken
0: branch 5 not taken
14: branch 6 taken
14: branch 7 taken
0: branch 8 not taken
0: branch 10 not taken
14: branch 11 taken
2344 14: if (InitVal.isUnknown() ||
2345 : !getConstraintManager().canReasonAbout(InitVal)) {
2346 : InitVal = ValMgr.getConjuredSymbolVal(NULL, InitEx,
2347 0: Builder->getCurrentBlockCount());
2348 : }
2349 :
2350 : EvalBind(Dst, S, S, N, state,
2351 14: loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true);
2352 14: }
2353 14: }
2354 :
2355 : namespace {
2356 : // This class is used by VisitInitListExpr as an item in a worklist
2357 : // for processing the values contained in an InitListExpr.
2358 1044: class InitListWLItem {
2359 : public:
2360 : llvm::ImmutableList<SVal> Vals;
2361 : ExplodedNode* N;
2362 : InitListExpr::reverse_iterator Itr;
2363 :
2364 : InitListWLItem(ExplodedNode* n, llvm::ImmutableList<SVal> vals,
2365 348: InitListExpr::reverse_iterator itr)
2366 348: : Vals(vals), N(n), Itr(itr) {}
2367 : };
2368 : }
2369 :
2370 :
2371 : void GRExprEngine::VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
2372 111: ExplodedNodeSet& Dst) {
2373 :
2374 111: const GRState* state = GetState(Pred);
2375 111: QualType T = getContext().getCanonicalType(E->getType());
2376 111: unsigned NumInitElements = E->getNumInits();
2377 :
65: branch 2 taken
46: branch 3 taken
27: branch 6 taken
38: branch 7 taken
22: branch 10 taken
5: branch 11 taken
20: branch 14 taken
2: branch 15 taken
109: branch 16 taken
2: branch 17 taken
2378 111: if (T->isArrayType() || T->isStructureType() ||
2379 : T->isUnionType() || T->isVectorType()) {
2380 :
2381 109: llvm::ImmutableList<SVal> StartVals = getBasicVals().getEmptySValList();
2382 :
2383 : // Handle base case where the initializer has no elements.
2384 : // e.g: static int* myArray[] = {};
2: branch 0 taken
107: branch 1 taken
2385 109: if (NumInitElements == 0) {
2386 2: SVal V = ValMgr.makeCompoundVal(T, StartVals);
2387 2: MakeNode(Dst, E, Pred, state->BindExpr(E, V));
2388 2: return;
2389 : }
2390 :
2391 : // Create a worklist to process the initializers.
2392 107: llvm::SmallVector<InitListWLItem, 10> WorkList;
2393 107: WorkList.reserve(NumInitElements);
2394 107: WorkList.push_back(InitListWLItem(Pred, StartVals, E->rbegin()));
2395 107: InitListExpr::reverse_iterator ItrEnd = E->rend();
0: branch 3 not taken
107: branch 4 taken
2396 107: assert(!(E->rbegin() == E->rend()));
2397 :
2398 : // Process the worklist until it is empty.
348: branch 2 taken
107: branch 3 taken
2399 455: while (!WorkList.empty()) {
2400 348: InitListWLItem X = WorkList.back();
2401 348: WorkList.pop_back();
2402 :
2403 348: ExplodedNodeSet Tmp;
2404 348: Visit(*X.Itr, X.N, Tmp);
2405 :
2406 348: InitListExpr::reverse_iterator NewItr = X.Itr + 1;
2407 :
348: branch 5 taken
348: branch 6 taken
2408 696: for (ExplodedNodeSet::iterator NI=Tmp.begin(),NE=Tmp.end();NI!=NE;++NI) {
2409 : // Get the last initializer value.
2410 348: state = GetState(*NI);
2411 348: SVal InitV = state->getSVal(cast<Expr>(*X.Itr));
2412 :
2413 : // Construct the new list of values by prepending the new value to
2414 : // the already constructed list.
2415 : llvm::ImmutableList<SVal> NewVals =
2416 348: getBasicVals().consVals(InitV, X.Vals);
2417 :
107: branch 1 taken
241: branch 2 taken
2418 348: if (NewItr == ItrEnd) {
2419 : // Now we have a list holding all init values. Make CompoundValData.
2420 107: SVal V = ValMgr.makeCompoundVal(T, NewVals);
2421 :
2422 : // Make final state and node.
2423 107: MakeNode(Dst, E, *NI, state->BindExpr(E, V));
2424 : }
2425 : else {
2426 : // Still some initializer values to go. Push them onto the worklist.
2427 241: WorkList.push_back(InitListWLItem(*NI, NewVals, NewItr));
2428 : }
2429 : }
2430 : }
2431 :
2432 107: return;
2433 : }
2434 :
2: branch 1 taken
0: branch 2 not taken
2: branch 5 taken
0: branch 6 not taken
2: branch 7 taken
0: branch 8 not taken
2435 2: if (Loc::IsLocType(T) || T->isIntegerType()) {
0: branch 1 not taken
2: branch 2 taken
2436 2: assert (E->getNumInits() == 1);
2437 2: ExplodedNodeSet Tmp;
2438 2: Expr* Init = E->getInit(0);
2439 2: Visit(Init, Pred, Tmp);
2: branch 4 taken
2: branch 5 taken
2440 4: for (ExplodedNodeSet::iterator I=Tmp.begin(), EI=Tmp.end(); I != EI; ++I) {
2441 2: state = GetState(*I);
2442 2: MakeNode(Dst, E, *I, state->BindExpr(E, state->getSVal(Init)));
2443 : }
2444 2: return;
2445 : }
2446 :
2447 0: assert(0 && "unprocessed InitListExpr type");
2448 : }
2449 :
2450 : /// VisitSizeOfAlignOfExpr - Transfer function for sizeof(type).
2451 : void GRExprEngine::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex,
2452 : ExplodedNode* Pred,
2453 98: ExplodedNodeSet& Dst) {
2454 98: QualType T = Ex->getTypeOfArgument();
2455 98: CharUnits amt;
2456 :
88: branch 1 taken
10: branch 2 taken
2457 98: if (Ex->isSizeOf()) {
20: branch 3 taken
68: branch 4 taken
2458 88: if (T == getContext().VoidTy) {
2459 : // sizeof(void) == 1 byte.
2460 20: amt = CharUnits::One();
2461 : }
24: branch 2 taken
44: branch 3 taken
2462 68: else if (!T.getTypePtr()->isConstantSizeType()) {
2463 : // FIXME: Add support for VLAs.
2464 24: Dst.Add(Pred);
2465 24: return;
2466 : }
0: branch 2 not taken
44: branch 3 taken
2467 44: else if (T->isObjCInterfaceType()) {
2468 : // Some code tries to take the sizeof an ObjCInterfaceType, relying that
2469 : // the compiler has laid out its representation. Just report Unknown
2470 : // for these.
2471 0: Dst.Add(Pred);
2472 0: return;
2473 : }
2474 : else {
2475 : // All other cases.
2476 44: amt = getContext().getTypeSizeInChars(T);
2477 : }
2478 : }
2479 : else // Get alignment of the type.
2480 10: amt = getContext().getTypeAlignInChars(T);
2481 :
2482 : MakeNode(Dst, Ex, Pred,
2483 : GetState(Pred)->BindExpr(Ex,
2484 74: ValMgr.makeIntVal(amt.getQuantity(), Ex->getType())));
2485 : }
2486 :
2487 :
2488 : void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
2489 2524: ExplodedNodeSet& Dst, bool asLValue) {
2490 :
861: branch 1 taken
707: branch 2 taken
8: branch 3 taken
4: branch 4 taken
100: branch 5 taken
0: branch 6 not taken
23: branch 7 taken
499: branch 8 taken
322: branch 9 taken
2491 2524: switch (U->getOpcode()) {
2492 :
2493 : default:
2494 : break;
2495 :
2496 : case UnaryOperator::Deref: {
2497 :
2498 707: Expr* Ex = U->getSubExpr()->IgnoreParens();
2499 707: ExplodedNodeSet Tmp;
2500 707: Visit(Ex, Pred, Tmp);
2501 :
707: branch 5 taken
707: branch 6 taken
2502 1414: for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
2503 :
2504 707: const GRState* state = GetState(*I);
2505 707: SVal location = state->getSVal(Ex);
2506 :
342: branch 0 taken
365: branch 1 taken
2507 707: if (asLValue)
2508 : MakeNode(Dst, U, *I, state->BindExpr(U, location),
2509 342: ProgramPoint::PostLValueKind);
2510 : else
2511 365: EvalLoad(Dst, U, *I, state, location);
2512 : }
2513 :
2514 707: return;
2515 : }
2516 :
2517 : case UnaryOperator::Real: {
2518 :
2519 8: Expr* Ex = U->getSubExpr()->IgnoreParens();
2520 8: ExplodedNodeSet Tmp;
2521 8: Visit(Ex, Pred, Tmp);
2522 :
8: branch 4 taken
8: branch 5 taken
2523 16: for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
2524 :
2525 : // FIXME: We don't have complex SValues yet.
0: branch 3 not taken
8: branch 4 taken
2526 8: if (Ex->getType()->isAnyComplexType()) {
2527 : // Just report "Unknown."
2528 0: Dst.Add(*I);
2529 0: continue;
2530 : }
2531 :
2532 : // For all other types, UnaryOperator::Real is an identity operation.
0: branch 3 not taken
8: branch 4 taken
2533 8: assert (U->getType() == Ex->getType());
2534 8: const GRState* state = GetState(*I);
2535 8: MakeNode(Dst, U, *I, state->BindExpr(U, state->getSVal(Ex)));
2536 : }
2537 :
2538 8: return;
2539 : }
2540 :
2541 : case UnaryOperator::Imag: {
2542 :
2543 4: Expr* Ex = U->getSubExpr()->IgnoreParens();
2544 4: ExplodedNodeSet Tmp;
2545 4: Visit(Ex, Pred, Tmp);
2546 :
4: branch 5 taken
4: branch 6 taken
2547 8: for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
2548 : // FIXME: We don't have complex SValues yet.
0: branch 3 not taken
4: branch 4 taken
2549 4: if (Ex->getType()->isAnyComplexType()) {
2550 : // Just report "Unknown."
2551 0: Dst.Add(*I);
2552 0: continue;
2553 : }
2554 :
2555 : // For all other types, UnaryOperator::Float returns 0.
0: branch 3 not taken
4: branch 4 taken
2556 4: assert (Ex->getType()->isIntegerType());
2557 4: const GRState* state = GetState(*I);
2558 4: SVal X = ValMgr.makeZeroVal(Ex->getType());
2559 4: MakeNode(Dst, U, *I, state->BindExpr(U, X));
2560 : }
2561 :
2562 4: return;
2563 : }
2564 :
2565 : case UnaryOperator::OffsetOf: {
2566 100: Expr::EvalResult Res;
100: branch 2 taken
0: branch 3 not taken
100: branch 5 taken
0: branch 6 not taken
100: branch 7 taken
0: branch 8 not taken
2567 100: if (U->Evaluate(Res, getContext()) && Res.Val.isInt()) {
2568 100: const APSInt &IV = Res.Val.getInt();
0: branch 4 not taken
100: branch 5 taken
2569 100: assert(IV.getBitWidth() == getContext().getTypeSize(U->getType()));
0: branch 3 not taken
100: branch 4 taken
2570 100: assert(U->getType()->isIntegerType());
0: branch 4 not taken
100: branch 5 taken
2571 100: assert(IV.isSigned() == U->getType()->isSignedIntegerType());
2572 100: SVal X = ValMgr.makeIntVal(IV);
2573 100: MakeNode(Dst, U, Pred, GetState(Pred)->BindExpr(U, X));
2574 100: return;
2575 : }
2576 : // FIXME: Handle the case where __builtin_offsetof is not a constant.
2577 0: Dst.Add(Pred);
2578 100: return;
2579 : }
2580 :
0: branch 0 not taken
0: branch 1 not taken
2581 0: case UnaryOperator::Plus: assert (!asLValue); // FALL-THROUGH.
2582 : case UnaryOperator::Extension: {
2583 :
2584 : // Unary "+" is a no-op, similar to a parentheses. We still have places
2585 : // where it may be a block-level expression, so we need to
2586 : // generate an extra node that just propagates the value of the
2587 : // subexpression.
2588 :
2589 23: Expr* Ex = U->getSubExpr()->IgnoreParens();
2590 23: ExplodedNodeSet Tmp;
2591 23: Visit(Ex, Pred, Tmp);
2592 :
23: branch 4 taken
23: branch 5 taken
2593 46: for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
2594 23: const GRState* state = GetState(*I);
2595 23: MakeNode(Dst, U, *I, state->BindExpr(U, state->getSVal(Ex)));
2596 : }
2597 :
2598 23: return;
2599 : }
2600 :
2601 : case UnaryOperator::AddrOf: {
2602 :
0: branch 0 not taken
499: branch 1 taken
2603 499: assert(!asLValue);
2604 499: Expr* Ex = U->getSubExpr()->IgnoreParens();
2605 499: ExplodedNodeSet Tmp;
2606 499: VisitLValue(Ex, Pred, Tmp);
2607 :
489: branch 5 taken
499: branch 6 taken
2608 988: for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
2609 489: const GRState* state = GetState(*I);
2610 489: SVal V = state->getSVal(Ex);
2611 489: state = state->BindExpr(U, V);
2612 489: MakeNode(Dst, U, *I, state);
2613 : }
2614 :
2615 499: return;
2616 : }
2617 :
2618 : case UnaryOperator::LNot:
2619 : case UnaryOperator::Minus:
2620 : case UnaryOperator::Not: {
2621 :
0: branch 0 not taken
322: branch 1 taken
2622 322: assert (!asLValue);
2623 322: Expr* Ex = U->getSubExpr()->IgnoreParens();
2624 322: ExplodedNodeSet Tmp;
2625 322: Visit(Ex, Pred, Tmp);
2626 :
294: branch 3 taken
45: branch 4 taken
339: branch 7 taken
322: branch 8 taken
2627 1000: for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
2628 339: const GRState* state = GetState(*I);
2629 :
2630 : // Get the value of the subexpression.
2631 339: SVal V = state->getSVal(Ex);
2632 :
45: branch 1 taken
294: branch 2 taken
2633 339: if (V.isUnknownOrUndef()) {
2634 45: MakeNode(Dst, U, *I, state->BindExpr(U, V));
2635 45: continue;
2636 : }
2637 :
2638 : // QualType DstT = getContext().getCanonicalType(U->getType());
2639 : // QualType SrcT = getContext().getCanonicalType(Ex->getType());
2640 : //
2641 : // if (DstT != SrcT) // Perform promotions.
2642 : // V = EvalCast(V, DstT);
2643 : //
2644 : // if (V.isUnknownOrUndef()) {
2645 : // MakeNode(Dst, U, *I, BindExpr(St, U, V));
2646 : // continue;
2647 : // }
2648 :
0: branch 1 not taken
34: branch 2 taken
18: branch 3 taken
242: branch 4 taken
2649 294: switch (U->getOpcode()) {
2650 : default:
2651 0: assert(false && "Invalid Opcode.");
2652 : break;
2653 :
2654 : case UnaryOperator::Not:
2655 : // FIXME: Do we need to handle promotions?
2656 34: state = state->BindExpr(U, EvalComplement(cast<NonLoc>(V)));
2657 34: break;
2658 :
2659 : case UnaryOperator::Minus:
2660 : // FIXME: Do we need to handle promotions?
2661 18: state = state->BindExpr(U, EvalMinus(cast<NonLoc>(V)));
2662 18: break;
2663 :
2664 : case UnaryOperator::LNot:
2665 :
2666 : // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
2667 : //
2668 : // Note: technically we do "E == 0", but this is the same in the
2669 : // transfer functions as "0 == E".
2670 242: SVal Result;
2671 :
106: branch 1 taken
136: branch 2 taken
2672 242: if (isa<Loc>(V)) {
2673 106: Loc X = ValMgr.makeNull();
2674 : Result = EvalBinOp(state, BinaryOperator::EQ, cast<Loc>(V), X,
2675 106: U->getType());
2676 : }
2677 : else {
2678 136: nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
2679 : Result = EvalBinOp(state, BinaryOperator::EQ, cast<NonLoc>(V), X,
2680 136: U->getType());
2681 : }
2682 :
2683 242: state = state->BindExpr(U, Result);
2684 :
2685 242: break;
2686 : }
2687 :
2688 294: MakeNode(Dst, U, *I, state);
2689 : }
2690 :
2691 322: return;
2692 : }
2693 : }
2694 :
2695 : // Handle ++ and -- (both pre- and post-increment).
2696 :
0: branch 1 not taken
861: branch 2 taken
2697 861: assert (U->isIncrementDecrementOp());
2698 861: ExplodedNodeSet Tmp;
2699 861: Expr* Ex = U->getSubExpr()->IgnoreParens();
2700 861: VisitLValue(Ex, Pred, Tmp);
2701 :
843: branch 6 taken
861: branch 7 taken
2702 1704: for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) {
2703 :
2704 843: const GRState* state = GetState(*I);
2705 843: SVal V1 = state->getSVal(Ex);
2706 :
2707 : // Perform a load.
2708 843: ExplodedNodeSet Tmp2;
2709 843: EvalLoad(Tmp2, Ex, *I, state, V1);
2710 :
825: branch 6 taken
10: branch 7 taken
835: branch 10 taken
843: branch 11 taken
2711 2503: for (ExplodedNodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end();I2!=E2;++I2) {
2712 :
2713 835: state = GetState(*I2);
2714 835: SVal V2_untested = state->getSVal(Ex);
2715 :
2716 : // Propagate unknown and undefined values.
10: branch 1 taken
825: branch 2 taken
2717 835: if (V2_untested.isUnknownOrUndef()) {
2718 10: MakeNode(Dst, U, *I2, state->BindExpr(U, V2_untested));
2719 10: continue;
2720 : }
2721 825: DefinedSVal V2 = cast<DefinedSVal>(V2_untested);
2722 :
2723 : // Handle all other values.
2724 : BinaryOperator::Opcode Op = U->isIncrementOp() ? BinaryOperator::Add
813: branch 1 taken
12: branch 2 taken
2725 825: : BinaryOperator::Sub;
2726 :
2727 : // If the UnaryOperator has non-location type, use its type to create the
2728 : // constant value. If the UnaryOperator has location type, create the
2729 : // constant with int type and pointer width.
2730 825: SVal RHS;
2731 :
176: branch 3 taken
649: branch 4 taken
2732 825: if (U->getType()->isAnyPointerType())
2733 176: RHS = ValMgr.makeIntValWithPtrWidth(1, false);
2734 : else
2735 649: RHS = ValMgr.makeIntVal(1, U->getType());
2736 :
2737 825: SVal Result = EvalBinOp(state, Op, V2, RHS, U->getType());
2738 :
2739 : // Conjure a new symbol if necessary to recover precision.
755: branch 1 taken
70: branch 2 taken
24: branch 5 taken
731: branch 6 taken
755: branch 7 taken
70: branch 8 taken
94: branch 10 taken
731: branch 11 taken
2740 825: if (Result.isUnknown() || !getConstraintManager().canReasonAbout(Result)){
2741 : DefinedOrUnknownSVal SymVal =
2742 : ValMgr.getConjuredSymbolVal(NULL, Ex,
2743 94: Builder->getCurrentBlockCount());
2744 94: Result = SymVal;
2745 :
2746 : // If the value is a location, ++/-- should always preserve
2747 : // non-nullness. Check if the original value was non-null, and if so
2748 : // propagate that constraint.
70: branch 2 taken
24: branch 3 taken
2749 94: if (Loc::IsLocType(U->getType())) {
2750 : DefinedOrUnknownSVal Constraint =
2751 70: SVator.EvalEQ(state, V2, ValMgr.makeZeroVal(U->getType()));
2752 :
23: branch 2 taken
47: branch 3 taken
2753 70: if (!state->Assume(Constraint, true)) {
2754 : // It isn't feasible for the original value to be null.
2755 : // Propagate this constraint.
2756 : Constraint = SVator.EvalEQ(state, SymVal,
2757 23: ValMgr.makeZeroVal(U->getType()));
2758 :
2759 :
2760 23: state = state->Assume(Constraint, false);
0: branch 0 not taken
23: branch 1 taken
2761 23: assert(state);
2762 70: }
2763 94: }
2764 : }
2765 :
418: branch 1 taken
407: branch 2 taken
2766 825: state = state->BindExpr(U, U->isPostfix() ? V2 : Result);
2767 :
2768 : // Perform the store.
2769 825: EvalStore(Dst, NULL, U, *I2, state, V1, Result);
2770 : }
2771 861: }
2772 : }
2773 :
2774 :
2775 : void GRExprEngine::VisitCXXThisExpr(CXXThisExpr *TE, ExplodedNode *Pred,
2776 10: ExplodedNodeSet & Dst) {
2777 : // Get the this object region from StoreManager.
2778 : const MemRegion *R =
2779 : ValMgr.getRegionManager().getCXXThisRegion(TE->getType(),
2780 10: Pred->getLocationContext());
2781 :
2782 10: const GRState *state = GetState(Pred);
2783 10: SVal V = state->getSVal(loc::MemRegionVal(R));
2784 10: MakeNode(Dst, TE, Pred, state->BindExpr(TE, V));
2785 10: }
2786 :
2787 : void GRExprEngine::VisitAsmStmt(AsmStmt* A, ExplodedNode* Pred,
2788 0: ExplodedNodeSet& Dst) {
2789 0: VisitAsmStmtHelperOutputs(A, A->begin_outputs(), A->end_outputs(), Pred, Dst);
2790 0: }
2791 :
2792 : void GRExprEngine::VisitAsmStmtHelperOutputs(AsmStmt* A,
2793 : AsmStmt::outputs_iterator I,
2794 : AsmStmt::outputs_iterator E,
2795 0: ExplodedNode* Pred, ExplodedNodeSet& Dst) {
0: branch 1 not taken
0: branch 2 not taken
2796 0: if (I == E) {
2797 0: VisitAsmStmtHelperInputs(A, A->begin_inputs(), A->end_inputs(), Pred, Dst);
2798 0: return;
2799 : }
2800 :
2801 0: ExplodedNodeSet Tmp;
2802 0: VisitLValue(*I, Pred, Tmp);
2803 :
2804 0: ++I;
2805 :
0: branch 4 not taken
0: branch 5 not taken
2806 0: for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end();NI != NE;++NI)
2807 0: VisitAsmStmtHelperOutputs(A, I, E, *NI, Dst);
2808 : }
2809 :
2810 : void GRExprEngine::VisitAsmStmtHelperInputs(AsmStmt* A,
2811 : AsmStmt::inputs_iterator I,
2812 : AsmStmt::inputs_iterator E,
2813 : ExplodedNode* Pred,
2814 0: ExplodedNodeSet& Dst) {
0: branch 1 not taken
0: branch 2 not taken
2815 0: if (I == E) {
2816 :
2817 : // We have processed both the inputs and the outputs. All of the outputs
2818 : // should evaluate to Locs. Nuke all of their values.
2819 :
2820 : // FIXME: Some day in the future it would be nice to allow a "plug-in"
2821 : // which interprets the inline asm and stores proper results in the
2822 : // outputs.
2823 :
2824 0: const GRState* state = GetState(Pred);
2825 :
0: branch 4 not taken
0: branch 5 not taken
2826 0: for (AsmStmt::outputs_iterator OI = A->begin_outputs(),
2827 0: OE = A->end_outputs(); OI != OE; ++OI) {
2828 :
2829 0: SVal X = state->getSVal(*OI);
0: branch 1 not taken
0: branch 2 not taken
2830 0: assert (!isa<NonLoc>(X)); // Should be an Lval, or unknown, undef.
2831 :
0: branch 1 not taken
0: branch 2 not taken
2832 0: if (isa<Loc>(X))
2833 0: state = state->bindLoc(cast<Loc>(X), UnknownVal());
2834 : }
2835 :
2836 0: MakeNode(Dst, A, Pred, state);
2837 0: return;
2838 : }
2839 :
2840 0: ExplodedNodeSet Tmp;
2841 0: Visit(*I, Pred, Tmp);
2842 :
2843 0: ++I;
2844 :
0: branch 4 not taken
0: branch 5 not taken
2845 0: for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI!=NE; ++NI)
2846 0: VisitAsmStmtHelperInputs(A, I, E, *NI, Dst);
2847 : }
2848 :
2849 : void GRExprEngine::VisitReturnStmt(ReturnStmt *RS, ExplodedNode *Pred,
2850 1400: ExplodedNodeSet &Dst) {
2851 :
2852 1400: ExplodedNodeSet Src;
1164: branch 1 taken
236: branch 2 taken
2853 1400: if (Expr *RetE = RS->getRetValue()) {
2854 1164: Visit(RetE, Pred, Src);
2855 : }
2856 : else {
2857 236: Src.Add(Pred);
2858 : }
2859 :
2860 1400: ExplodedNodeSet CheckedSet;
2861 1400: CheckerVisit(RS, CheckedSet, Src, true);
2862 :
1305: branch 6 taken
1400: branch 7 taken
2863 2705: for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
2864 : I != E; ++I) {
2865 :
0: branch 0 not taken
1305: branch 1 taken
2866 1305: assert(Builder && "GRStmtNodeBuilder must be defined.");
2867 :
2868 1305: Pred = *I;
2869 1305: unsigned size = Dst.size();
2870 :
2871 1305: SaveAndRestore<bool> OldSink(Builder->BuildSinks);
2872 1305: SaveOr OldHasGen(Builder->HasGeneratedNode);
2873 :
2874 1305: getTF().EvalReturn(Dst, *this, *Builder, RS, Pred);
2875 :
2876 : // Handle the case where no nodes where generated.
1305: branch 0 taken
0: branch 1 not taken
1198: branch 3 taken
107: branch 4 taken
1198: branch 5 taken
0: branch 6 not taken
1198: branch 7 taken
107: branch 8 taken
2877 1305: if (!Builder->BuildSinks && Dst.size() == size &&
2878 : !Builder->HasGeneratedNode)
2879 1198: MakeNode(Dst, RS, Pred, GetState(Pred));
2880 1400: }
2881 1400: }
2882 :
2883 : //===----------------------------------------------------------------------===//
2884 : // Transfer functions: Binary operators.
2885 : //===----------------------------------------------------------------------===//
2886 :
2887 : void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
2888 : ExplodedNode* Pred,
2889 3432: ExplodedNodeSet& Dst, bool asLValue) {
2890 :
2891 3432: ExplodedNodeSet Tmp1;
2892 3432: Expr* LHS = B->getLHS()->IgnoreParens();
2893 3432: Expr* RHS = B->getRHS()->IgnoreParens();
2894 :
2895 : // FIXME: Add proper support for ObjCImplicitSetterGetterRefExpr.
12: branch 1 taken
3420: branch 2 taken
2896 3432: if (isa<ObjCImplicitSetterGetterRefExpr>(LHS)) {
2897 12: Visit(RHS, Pred, Dst);
2898 12: return;
2899 : }
2900 :
1434: branch 1 taken
1986: branch 2 taken
2901 3420: if (B->isAssignmentOp())
2902 1434: VisitLValue(LHS, Pred, Tmp1);
2903 : else
2904 1986: Visit(LHS, Pred, Tmp1);
2905 :
2906 3420: ExplodedNodeSet Tmp3;
2907 :
3398: branch 7 taken
3420: branch 8 taken
2908 6818: for (ExplodedNodeSet::iterator I1=Tmp1.begin(), E1=Tmp1.end(); I1!=E1; ++I1) {
2909 3398: SVal LeftV = (*I1)->getState()->getSVal(LHS);
2910 3398: ExplodedNodeSet Tmp2;
2911 3398: Visit(RHS, *I1, Tmp2);
2912 :
2913 3398: ExplodedNodeSet CheckedSet;
2914 3398: CheckerVisit(B, CheckedSet, Tmp2, true);
2915 :
2916 : // With both the LHS and RHS evaluated, process the operation itself.
2917 :
144: branch 3 taken
3242: branch 4 taken
3386: branch 7 taken
3398: branch 8 taken
2918 6784: for (ExplodedNodeSet::iterator I2=CheckedSet.begin(), E2=CheckedSet.end();
2919 : I2 != E2; ++I2) {
2920 :
2921 3386: const GRState *state = GetState(*I2);
2922 3386: const GRState *OldSt = state;
2923 3386: SVal RightV = state->getSVal(RHS);
2924 :
2925 3386: BinaryOperator::Opcode Op = B->getOpcode();
2926 :
1272: branch 0 taken
2114: branch 1 taken
2927 3386: if (Op == BinaryOperator::Assign) {
2928 : // EXPERIMENTAL: "Conjured" symbols.
2929 : // FIXME: Handle structs.
2930 1272: QualType T = RHS->getType();
2931 :
1108: branch 1 taken
164: branch 2 taken
4: branch 5 taken
1104: branch 6 taken
156: branch 8 taken
12: branch 9 taken
156: branch 12 taken
0: branch 13 not taken
118: branch 16 taken
38: branch 17 taken
1108: branch 18 taken
164: branch 19 taken
130: branch 21 taken
1142: branch 22 taken
2932 1272: if ((RightV.isUnknown()||!getConstraintManager().canReasonAbout(RightV))
2933 : && (Loc::IsLocType(T) || (T->isScalarType()&&T->isIntegerType()))) {
2934 130: unsigned Count = Builder->getCurrentBlockCount();
2935 130: RightV = ValMgr.getConjuredSymbolVal(NULL, B->getRHS(), Count);
2936 : }
2937 :
6: branch 0 taken
1266: branch 1 taken
2938 1272: SVal ExprVal = asLValue ? LeftV : RightV;
2939 :
2940 : // Simulate the effects of a "store": bind the value of the RHS
2941 : // to the L-Value represented by the LHS.
2942 1272: EvalStore(Tmp3, B, LHS, *I2, state->BindExpr(B, ExprVal), LeftV,RightV);
2943 1272: continue;
2944 : }
2945 :
1970: branch 1 taken
144: branch 2 taken
2946 2114: if (!B->isAssignmentOp()) {
2947 : // Process non-assignments except commas or short-circuited
2948 : // logical expressions (LAnd and LOr).
2949 1970: SVal Result = EvalBinOp(state, Op, LeftV, RightV, B->getType());
2950 :
366: branch 1 taken
1604: branch 2 taken
2951 1970: if (Result.isUnknown()) {
0: branch 0 not taken
366: branch 1 taken
2952 366: if (OldSt != state) {
2953 : // Generate a new node if we have already created a new state.
2954 0: MakeNode(Tmp3, B, *I2, state);
2955 : }
2956 : else
2957 366: Tmp3.Add(*I2);
2958 :
2959 : continue;
2960 : }
2961 :
2962 1604: state = state->BindExpr(B, Result);
2963 :
2964 1604: MakeNode(Tmp3, B, *I2, state);
2965 1970: continue;
2966 : }
2967 :
0: branch 1 not taken
144: branch 2 taken
2968 144: assert (B->isCompoundAssignmentOp());
2969 :
0: branch 0 not taken
0: branch 1 not taken
10: branch 2 taken
0: branch 3 not taken
30: branch 4 taken
0: branch 5 not taken
60: branch 6 taken
0: branch 7 not taken
14: branch 8 taken
0: branch 9 not taken
30: branch 10 taken
2970 144: switch (Op) {
2971 : default:
2972 0: assert(0 && "Invalid opcode for compound assignment.");
2973 0: case BinaryOperator::MulAssign: Op = BinaryOperator::Mul; break;
2974 10: case BinaryOperator::DivAssign: Op = BinaryOperator::Div; break;
2975 0: case BinaryOperator::RemAssign: Op = BinaryOperator::Rem; break;
2976 30: case BinaryOperator::AddAssign: Op = BinaryOperator::Add; break;
2977 0: case BinaryOperator::SubAssign: Op = BinaryOperator::Sub; break;
2978 60: case BinaryOperator::ShlAssign: Op = BinaryOperator::Shl; break;
2979 0: case BinaryOperator::ShrAssign: Op = BinaryOperator::Shr; break;
2980 14: case BinaryOperator::AndAssign: Op = BinaryOperator::And; break;
2981 0: case BinaryOperator::XorAssign: Op = BinaryOperator::Xor; break;
2982 30: case BinaryOperator::OrAssign: Op = BinaryOperator::Or; break;
2983 : }
2984 :
2985 : // Perform a load (the LHS). This performs the checks for
2986 : // null dereferences, and so on.
2987 144: ExplodedNodeSet Tmp4;
2988 144: SVal location = state->getSVal(LHS);
2989 144: EvalLoad(Tmp4, LHS, *I2, state, location);
2990 :
140: branch 7 taken
144: branch 8 taken
2991 284: for (ExplodedNodeSet::iterator I4=Tmp4.begin(), E4=Tmp4.end(); I4!=E4;
2992 : ++I4) {
2993 140: state = GetState(*I4);
2994 140: SVal V = state->getSVal(LHS);
2995 :
2996 : // Get the computation type.
2997 : QualType CTy =
2998 140: cast<CompoundAssignOperator>(B)->getComputationResultType();
2999 140: CTy = getContext().getCanonicalType(CTy);
3000 :
3001 : QualType CLHSTy =
3002 140: cast<CompoundAssignOperator>(B)->getComputationLHSType();
3003 140: CLHSTy = getContext().getCanonicalType(CLHSTy);
3004 :
3005 140: QualType LTy = getContext().getCanonicalType(LHS->getType());
3006 140: QualType RTy = getContext().getCanonicalType(RHS->getType());
3007 :
3008 : // Promote LHS.
3009 140: V = SVator.EvalCast(V, CLHSTy, LTy);
3010 :
3011 : // Compute the result of the operation.
3012 : SVal Result = SVator.EvalCast(EvalBinOp(state, Op, V, RightV, CTy),
3013 140: B->getType(), CTy);
3014 :
3015 : // EXPERIMENTAL: "Conjured" symbols.
3016 : // FIXME: Handle structs.
3017 :
3018 140: SVal LHSVal;
3019 :
68: branch 1 taken
72: branch 2 taken
2: branch 5 taken
66: branch 6 taken
66: branch 8 taken
8: branch 9 taken
66: branch 12 taken
0: branch 13 not taken
56: branch 16 taken
10: branch 17 taken
68: branch 18 taken
72: branch 19 taken
64: branch 21 taken
76: branch 22 taken
3020 140: if ((Result.isUnknown() ||
3021 : !getConstraintManager().canReasonAbout(Result))
3022 : && (Loc::IsLocType(CTy)
3023 : || (CTy->isScalarType() && CTy->isIntegerType()))) {
3024 :
3025 64: unsigned Count = Builder->getCurrentBlockCount();
3026 :
3027 : // The symbolic value is actually for the type of the left-hand side
3028 : // expression, not the computation type, as this is the value the
3029 : // LValue on the LHS will bind to.
3030 64: LHSVal = ValMgr.getConjuredSymbolVal(NULL, B->getRHS(), LTy, Count);
3031 :
3032 : // However, we need to convert the symbol to the computation type.
3033 64: Result = SVator.EvalCast(LHSVal, CTy, LTy);
3034 : }
3035 : else {
3036 : // The left-hand side may bind to a different value then the
3037 : // computation type.
3038 76: LHSVal = SVator.EvalCast(Result, LTy, CTy);
3039 : }
3040 :
3041 : EvalStore(Tmp3, B, LHS, *I4, state->BindExpr(B, Result),
3042 140: location, LHSVal);
3043 : }
3044 144: }
3045 : }
3046 :
3420: branch 3 taken
12: branch 4 taken
3047 3420: CheckerVisit(B, Dst, Tmp3, false);
3048 : }
3049 :
3050 : void GRExprEngine::CreateCXXTemporaryObject(Expr *Ex, ExplodedNode *Pred,
3051 1: ExplodedNodeSet &Dst) {
3052 1: ExplodedNodeSet Tmp;
3053 1: Visit(Ex, Pred, Tmp);
1: branch 5 taken
1: branch 6 taken
3054 2: for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) {
3055 1: const GRState *state = GetState(*I);
3056 :
3057 : // Bind the temporary object to the value of the expression. Then bind
3058 : // the expression to the location of the object.
3059 1: SVal V = state->getSVal(Ex);
3060 :
3061 : const MemRegion *R =
3062 : ValMgr.getRegionManager().getCXXObjectRegion(Ex,
3063 1: Pred->getLocationContext());
3064 :
3065 1: state = state->bindLoc(loc::MemRegionVal(R), V);
3066 1: MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, loc::MemRegionVal(R)));
3067 1: }
3068 1: }
3069 :
3070 : //===----------------------------------------------------------------------===//
3071 : // Checker registration/lookup.
3072 : //===----------------------------------------------------------------------===//
3073 :
3074 24: Checker *GRExprEngine::lookupChecker(void *tag) const {
3075 24: CheckerMap::const_iterator I = CheckerM.find(tag);
0: branch 2 not taken
24: branch 3 taken
3076 24: return (I == CheckerM.end()) ? NULL : Checkers[I->second].second;
3077 : }
3078 :
3079 : //===----------------------------------------------------------------------===//
3080 : // Visualization.
3081 : //===----------------------------------------------------------------------===//
3082 :
3083 : #ifndef NDEBUG
3084 : static GRExprEngine* GraphPrintCheckerState;
3085 : static SourceManager* GraphPrintSourceManager;
3086 :
3087 : namespace llvm {
3088 : template<>
3089 : struct DOTGraphTraits<ExplodedNode*> :
3090 : public DefaultDOTGraphTraits {
3091 :
3092 0: DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
3093 :
3094 : // FIXME: Since we do not cache error nodes in GRExprEngine now, this does not
3095 : // work.
3096 0: static std::string getNodeAttributes(const ExplodedNode* N, void*) {
3097 :
3098 : #if 0
3099 : // FIXME: Replace with a general scheme to tell if the node is
3100 : // an error node.
3101 : if (GraphPrintCheckerState->isImplicitNullDeref(N) ||
3102 : GraphPrintCheckerState->isExplicitNullDeref(N) ||
3103 : GraphPrintCheckerState->isUndefDeref(N) ||
3104 : GraphPrintCheckerState->isUndefStore(N) ||
3105 : GraphPrintCheckerState->isUndefControlFlow(N) ||
3106 : GraphPrintCheckerState->isUndefResult(N) ||
3107 : GraphPrintCheckerState->isBadCall(N) ||
3108 : GraphPrintCheckerState->isUndefArg(N))
3109 : return "color=\"red\",style=\"filled\"";
3110 :
3111 : if (GraphPrintCheckerState->isNoReturnCall(N))
3112 : return "color=\"blue\",style=\"filled\"";
3113 : #endif
3114 0: return "";
3115 : }
3116 :
3117 0: static std::string getNodeLabel(const ExplodedNode* N, void*){
3118 :
3119 0: std::string sbuf;
3120 0: llvm::raw_string_ostream Out(sbuf);
3121 :
3122 : // Program Location.
3123 0: ProgramPoint Loc = N->getLocation();
3124 :
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
3125 0: switch (Loc.getKind()) {
3126 : case ProgramPoint::BlockEntranceKind:
3127 : Out << "Block Entrance: B"
3128 0: << cast<BlockEntrance>(Loc).getBlock()->getBlockID();
3129 0: break;
3130 :
3131 : case ProgramPoint::BlockExitKind:
3132 0: assert (false);
3133 : break;
3134 :
3135 : default: {
0: branch 1 not taken
0: branch 2 not taken
3136 0: if (StmtPoint *L = dyn_cast<StmtPoint>(&Loc)) {
3137 0: const Stmt* S = L->getStmt();
3138 0: SourceLocation SLoc = S->getLocStart();
3139 :
3140 0: Out << S->getStmtClassName() << ' ' << (void*) S << ' ';
3141 0: LangOptions LO; // FIXME.
3142 0: S->printPretty(Out, 0, PrintingPolicy(LO));
3143 :
0: branch 1 not taken
0: branch 2 not taken
3144 0: if (SLoc.isFileID()) {
3145 : Out << "\\lline="
3146 : << GraphPrintSourceManager->getInstantiationLineNumber(SLoc)
3147 : << " col="
3148 : << GraphPrintSourceManager->getInstantiationColumnNumber(SLoc)
3149 0: << "\\l";
3150 : }
3151 :
0: branch 1 not taken
0: branch 2 not taken
3152 0: if (isa<PreStmt>(Loc))
3153 0: Out << "\\lPreStmt\\l;";
0: branch 1 not taken
0: branch 2 not taken
3154 0: else if (isa<PostLoad>(Loc))
3155 0: Out << "\\lPostLoad\\l;";
0: branch 1 not taken
0: branch 2 not taken
3156 0: else if (isa<PostStore>(Loc))
3157 0: Out << "\\lPostStore\\l";
0: branch 1 not taken
0: branch 2 not taken
3158 0: else if (isa<PostLValue>(Loc))
3159 0: Out << "\\lPostLValue\\l";
3160 :
3161 : #if 0
3162 : // FIXME: Replace with a general scheme to determine
3163 : // the name of the check.
3164 : if (GraphPrintCheckerState->isImplicitNullDeref(N))
3165 : Out << "\\|Implicit-Null Dereference.\\l";
3166 : else if (GraphPrintCheckerState->isExplicitNullDeref(N))
3167 : Out << "\\|Explicit-Null Dereference.\\l";
3168 : else if (GraphPrintCheckerState->isUndefDeref(N))
3169 : Out << "\\|Dereference of undefialied value.\\l";
3170 : else if (GraphPrintCheckerState->isUndefStore(N))
3171 : Out << "\\|Store to Undefined Loc.";
3172 : else if (GraphPrintCheckerState->isUndefResult(N))
3173 : Out << "\\|Result of operation is undefined.";
3174 : else if (GraphPrintCheckerState->isNoReturnCall(N))
3175 : Out << "\\|Call to function marked \"noreturn\".";
3176 : else if (GraphPrintCheckerState->isBadCall(N))
3177 : Out << "\\|Call to NULL/Undefined.";
3178 : else if (GraphPrintCheckerState->isUndefArg(N))
3179 : Out << "\\|Argument in call is undefined";
3180 : #endif
3181 :
3182 0: break;
3183 : }
3184 :
3185 0: const BlockEdge& E = cast<BlockEdge>(Loc);
3186 : Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
3187 0: << E.getDst()->getBlockID() << ')';
3188 :
0: branch 2 not taken
0: branch 3 not taken
3189 0: if (Stmt* T = E.getSrc()->getTerminator()) {
3190 :
3191 0: SourceLocation SLoc = T->getLocStart();
3192 :
3193 0: Out << "\\|Terminator: ";
3194 0: LangOptions LO; // FIXME.
3195 0: E.getSrc()->printTerminator(Out, LO);
3196 :
0: branch 1 not taken
0: branch 2 not taken
3197 0: if (SLoc.isFileID()) {
3198 : Out << "\\lline="
3199 : << GraphPrintSourceManager->getInstantiationLineNumber(SLoc)
3200 : << " col="
3201 0: << GraphPrintSourceManager->getInstantiationColumnNumber(SLoc);
3202 : }
3203 :
0: branch 1 not taken
0: branch 2 not taken
3204 0: if (isa<SwitchStmt>(T)) {
3205 0: Stmt* Label = E.getDst()->getLabel();
3206 :
0: branch 0 not taken
0: branch 1 not taken
3207 0: if (Label) {
0: branch 1 not taken
0: branch 2 not taken
3208 0: if (CaseStmt* C = dyn_cast<CaseStmt>(Label)) {
3209 0: Out << "\\lcase ";
3210 0: LangOptions LO; // FIXME.
3211 0: C->getLHS()->printPretty(Out, 0, PrintingPolicy(LO));
3212 :
0: branch 1 not taken
0: branch 2 not taken
3213 0: if (Stmt* RHS = C->getRHS()) {
3214 0: Out << " .. ";
3215 0: RHS->printPretty(Out, 0, PrintingPolicy(LO));
3216 : }
3217 :
3218 0: Out << ":";
3219 : }
3220 : else {
0: branch 1 not taken
0: branch 2 not taken
3221 0: assert (isa<DefaultStmt>(Label));
3222 0: Out << "\\ldefault:";
3223 : }
3224 : }
3225 : else
3226 0: Out << "\\l(implicit) default:";
3227 : }
0: branch 1 not taken
0: branch 2 not taken
3228 0: else if (isa<IndirectGotoStmt>(T)) {
3229 : // FIXME
3230 : }
3231 : else {
3232 0: Out << "\\lCondition: ";
0: branch 3 not taken
0: branch 4 not taken
3233 0: if (*E.getSrc()->succ_begin() == E.getDst())
3234 0: Out << "true";
3235 : else
3236 0: Out << "false";
3237 : }
3238 :
3239 0: Out << "\\l";
3240 : }
3241 :
3242 : #if 0
3243 : // FIXME: Replace with a general scheme to determine
3244 : // the name of the check.
3245 : if (GraphPrintCheckerState->isUndefControlFlow(N)) {
3246 : Out << "\\|Control-flow based on\\lUndefined value.\\l";
3247 : }
3248 : #endif
3249 : }
3250 : }
3251 :
3252 0: Out << "\\|StateID: " << (void*) N->getState() << "\\|";
3253 :
3254 0: const GRState *state = N->getState();
3255 0: state->printDOT(Out);
3256 :
3257 0: Out << "\\l";
3258 0: return Out.str();
3259 : }
3260 : };
3261 : } // end llvm namespace
3262 : #endif
3263 :
3264 : #ifndef NDEBUG
3265 : template <typename ITERATOR>
3266 : ExplodedNode* GetGraphNode(ITERATOR I) { return *I; }
3267 :
3268 : template <> ExplodedNode*
3269 : GetGraphNode<llvm::DenseMap<ExplodedNode*, Expr*>::iterator>
3270 0: (llvm::DenseMap<ExplodedNode*, Expr*>::iterator I) {
3271 0: return I->first;
3272 : }
3273 : #endif
3274 :
3275 0: void GRExprEngine::ViewGraph(bool trim) {
3276 : #ifndef NDEBUG
0: branch 0 not taken
0: branch 1 not taken
3277 0: if (trim) {
3278 0: std::vector<ExplodedNode*> Src;
3279 :
3280 : // Flush any outstanding reports to make sure we cover all the nodes.
3281 : // This does not cause them to get displayed.
0: branch 4 not taken
0: branch 5 not taken
3282 0: for (BugReporter::iterator I=BR.begin(), E=BR.end(); I!=E; ++I)
3283 0: const_cast<BugType*>(*I)->FlushReports(BR);
3284 :
3285 : // Iterate through the reports and get their nodes.
0: branch 4 not taken
0: branch 5 not taken
3286 0: for (BugReporter::iterator I=BR.begin(), E=BR.end(); I!=E; ++I) {
0: branch 6 not taken
0: branch 7 not taken
3287 0: for (BugType::const_iterator I2=(*I)->begin(), E2=(*I)->end();
3288 : I2!=E2; ++I2) {
3289 0: const BugReportEquivClass& EQ = *I2;
3290 0: const BugReport &R = **EQ.begin();
3291 0: ExplodedNode *N = const_cast<ExplodedNode*>(R.getEndNode());
0: branch 0 not taken
0: branch 1 not taken
3292 0: if (N) Src.push_back(N);
3293 : }
3294 0: }
3295 :
3296 0: ViewGraph(&Src[0], &Src[0]+Src.size());