ExprEngine.cpp revision 603513d2294c437b37bcf47f326b686e31bd9e84
1d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis//=-- ExprEngine.cpp - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=
264924859b6b09d1cfb62fecf5954ec6c27cb58feTed Kremenek//
34af84313df0d2710fd57af89132e680294225cadTed Kremenek//                     The LLVM Compiler Infrastructure
4d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek//
5d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek// This file is distributed under the University of Illinois Open Source
6d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek// License. See LICENSE.TXT for details.
7d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek//
8d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek//===----------------------------------------------------------------------===//
9d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek//
1077349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek//  This file defines a meta-engine for path-sensitive dataflow analysis that
1177349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek//  is built on GREngine, but provides the boilerplate to execute transfer
1277349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek//  functions and build the ExplodedGraph at the expression level.
13d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek//
14d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek//===----------------------------------------------------------------------===//
15a7af5ea88a6c5bdf87497cca6c20831e8c546751Argyrios Kyrtzidis
16c2994283aa7538b7420c8e398cde7afa328d7042Anna Zaks#define DEBUG_TYPE "ExprEngine"
17c2994283aa7538b7420c8e398cde7afa328d7042Anna Zaks
1843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerManager.h"
199b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
209b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
21f540c54701e3eeb34cb619a3a4eb18f1ac70ef2dJordan Rose#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
229b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
23199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck#include "clang/AST/CharUnits.h"
2416f0049415ec596504891259e2a83e19871c0d52Chris Lattner#include "clang/AST/ParentMap.h"
2516f0049415ec596504891259e2a83e19871c0d52Chris Lattner#include "clang/AST/StmtObjC.h"
26337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek#include "clang/AST/StmtCXX.h"
271b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner#include "clang/Basic/Builtins.h"
2816f0049415ec596504891259e2a83e19871c0d52Chris Lattner#include "clang/Basic/SourceManager.h"
290bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek#include "clang/Basic/PrettyStackTrace.h"
30a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek#include "llvm/Support/raw_ostream.h"
316cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer#include "llvm/ADT/ImmutableList.h"
32c2994283aa7538b7420c8e398cde7afa328d7042Anna Zaks#include "llvm/ADT/Statistic.h"
334323a57627e796dcfdfdb7d47672dc09ed308edaTed Kremenek
340f5f0595d6a038843a7051c5a65fca7bce2915a0Ted Kremenek#ifndef NDEBUG
350f5f0595d6a038843a7051c5a65fca7bce2915a0Ted Kremenek#include "llvm/Support/GraphWriter.h"
360f5f0595d6a038843a7051c5a65fca7bce2915a0Ted Kremenek#endif
370f5f0595d6a038843a7051c5a65fca7bce2915a0Ted Kremenek
38b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenekusing namespace clang;
399ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento;
40b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenekusing llvm::APSInt;
41ab2b8c54bca82866876f91e756788916d3fa20c3Ted Kremenek
42c2994283aa7538b7420c8e398cde7afa328d7042Anna ZaksSTATISTIC(NumRemoveDeadBindings,
43c2994283aa7538b7420c8e398cde7afa328d7042Anna Zaks            "The # of times RemoveDeadBindings is called");
44749bbe6f5f23676244f12a0d41511c8e73516febAnna ZaksSTATISTIC(NumMaxBlockCountReached,
45749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks            "The # of aborted paths due to reaching the maximum block count in "
46749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks            "a top level function");
47749bbe6f5f23676244f12a0d41511c8e73516febAnna ZaksSTATISTIC(NumMaxBlockCountReachedInInlined,
48749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks            "The # of aborted paths due to reaching the maximum block count in "
49749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks            "an inlined function");
505903a373db3d27794c90b25687e0dd6adb0e497dAnna ZaksSTATISTIC(NumTimesRetriedWithoutInlining,
515903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks            "The # of times we re-evaluated a call without inlining");
525903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
53e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===//
54bdb435ddaafd5069becd543d638112f68825b89dTed Kremenek// Engine construction and deletion.
55bdb435ddaafd5069becd543d638112f68825b89dTed Kremenek//===----------------------------------------------------------------------===//
56bdb435ddaafd5069becd543d638112f68825b89dTed Kremenek
573fd5f370a28552976c52e76c3035d79012d78ddaAnna ZaksExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled,
58fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks                       SetOfConstDecls *VisitedCalleesIn,
593bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks                       FunctionSummariesTy *FS)
6025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  : AMgr(mgr),
611d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek    AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()),
62fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks    Engine(*this, FS),
63d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis    G(Engine.getGraph()),
64c77a55126fcad66fb086f8e100a494caa2496a2dZhongxing Xu    StateMgr(getContext(), mgr.getStoreManagerCreator(),
6532a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek             mgr.getConstraintManagerCreator(), G.getAllocator(),
66ca5d78d0bc3010164f2f9682967d64d7e305a167Jordan Rose             this),
6750a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek    SymMgr(StateMgr.getSymbolManager()),
68c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    svalBuilder(StateMgr.getSValBuilder()),
698ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks    EntryNode(NULL),
7066c486f275531df6362b3511fc3af6563561801bTed Kremenek    currStmt(NULL), currStmtIdx(0), currBldrCtx(0),
714ef19205b6912316296db74a9073ad6fa60e4ccaTed Kremenek    ObjCNoRet(mgr.getASTContext()),
72fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks    ObjCGCEnabled(gcEnabled), BR(mgr, *this),
73fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks    VisitedCallees(VisitedCalleesIn)
74255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek{
754d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose  unsigned TrimInterval = mgr.options.getGraphTrimInterval();
764d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose  if (TrimInterval != 0) {
774d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose    // Enable eager node reclaimation when constructing the ExplodedGraph.
784d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose    G.enableNodeReclamation(TrimInterval);
794d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose  }
80c80135ba857da48173578b9c528fce6777e18168Ted Kremenek}
8150a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek
82d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios KyrtzidisExprEngine::~ExprEngine() {
83cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  BR.FlushReports();
8450a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek}
8550a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek
86e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===//
87e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek// Utility methods.
88e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===//
89e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek
908bef8238181a30e52dea380789a7e2d760eac532Ted KremenekProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) {
918bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef state = StateMgr.getInitialState(InitLoc);
92a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek  const Decl *D = InitLoc->getDecl();
931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
94cfcd7fd0de701c5ce05e96de1ed2d0bf8c7035d9Ted Kremenek  // Preconditions.
9552e5602056e4cade24cbcca57767e94e1d430b03Ted Kremenek  // FIXME: It would be nice if we had a more general mechanism to add
9652e5602056e4cade24cbcca57767e94e1d430b03Ted Kremenek  // such preconditions.  Some day.
975974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek  do {
98a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek
995974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1005974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek      // Precondition: the first argument of 'main' is an integer guaranteed
1015974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek      //  to be > 0.
1025974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek      const IdentifierInfo *II = FD->getIdentifier();
1035974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek      if (!II || !(II->getName() == "main" && FD->getNumParams() > 0))
1045974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek        break;
1055974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek
1065974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek      const ParmVarDecl *PD = FD->getParamDecl(0);
1075974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek      QualType T = PD->getType();
1085974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek      if (!T->isIntegerType())
1095974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek        break;
110b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
1115974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek      const MemRegion *R = state->getRegion(PD, InitLoc);
1125974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek      if (!R)
1135974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek        break;
114b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
1151397663af9dbcc24dbf0e11de43931b3dc08fdbbTed Kremenek      SVal V = state->getSVal(loc::MemRegionVal(R));
1169c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek      SVal Constraint_untested = evalBinOp(state, BO_GT, V,
117c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek                                           svalBuilder.makeZeroVal(T),
1185974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek                                           getContext().IntTy);
1195974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek
1205974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek      DefinedOrUnknownSVal *Constraint =
1215974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek        dyn_cast<DefinedOrUnknownSVal>(&Constraint_untested);
122b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
1235974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek      if (!Constraint)
1245974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek        break;
125b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
1268bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek      if (ProgramStateRef newState = state->assume(*Constraint, true))
1275974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek        state = newState;
12852e5602056e4cade24cbcca57767e94e1d430b03Ted Kremenek    }
129a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek    break;
130a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek  }
131a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek  while (0);
132a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek
133a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
134a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek    // Precondition: 'self' is always non-null upon entry to an Objective-C
135a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek    // method.
136a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek    const ImplicitParamDecl *SelfD = MD->getSelfDecl();
137a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek    const MemRegion *R = state->getRegion(SelfD, InitLoc);
138a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek    SVal V = state->getSVal(loc::MemRegionVal(R));
139a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek
140a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek    if (const Loc *LV = dyn_cast<Loc>(&V)) {
141a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek      // Assume that the pointer value in 'self' is non-null.
142a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek      state = state->assume(*LV, true);
143a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek      assert(state && "'self' cannot be null");
144a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek    }
145a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek  }
1465974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek
147a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
148a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek    if (!MD->isStatic()) {
149a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek      // Precondition: 'this' is always non-null upon entry to the
150a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek      // top-level function.  This is our starting assumption for
151a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek      // analyzing an "open" program.
152a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek      const StackFrameContext *SFC = InitLoc->getCurrentStackFrame();
153a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek      if (SFC->getParent() == 0) {
15410f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek        loc::MemRegionVal L = svalBuilder.getCXXThis(MD, SFC);
155a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek        SVal V = state->getSVal(L);
156a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek        if (const Loc *LV = dyn_cast<Loc>(&V)) {
157a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek          state = state->assume(*LV, true);
158a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek          assert(state && "'this' cannot be null");
159a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek        }
1605974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek      }
161cfcd7fd0de701c5ce05e96de1ed2d0bf8c7035d9Ted Kremenek    }
162a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek  }
163a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek
16452e5602056e4cade24cbcca57767e94e1d430b03Ted Kremenek  return state;
165e070a1df66aab6d4168fb28f7559fdf996df3567Ted Kremenek}
166e070a1df66aab6d4168fb28f7559fdf996df3567Ted Kremenek
167f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose/// If the value of the given expression is a NonLoc, copy it into a new
168f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose/// temporary region, and replace the value of the expression with that.
169f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rosestatic ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State,
170f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose                                                     const LocationContext *LC,
171f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose                                                     const Expr *E) {
172f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  SVal V = State->getSVal(E, LC);
173f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
174f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  if (isa<NonLoc>(V)) {
175f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose    MemRegionManager &MRMgr = State->getStateManager().getRegionManager();
176f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose    const MemRegion *R  = MRMgr.getCXXTempObjectRegion(E, LC);
177f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose    State = State->bindLoc(loc::MemRegionVal(R), V);
178f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose    State = State->BindExpr(E, LC, loc::MemRegionVal(R));
179f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  }
180f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
181f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  return State;
182f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose}
183f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
184e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===//
185e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek// Top-level transfer function logic (Dispatcher).
186e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===//
187e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek
1889c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek/// evalAssume - Called by ConstraintManager. Used to call checker-specific
18932a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek///  logic for handling assumptions on symbolic values.
1908bef8238181a30e52dea380789a7e2d760eac532Ted KremenekProgramStateRef ExprEngine::processAssume(ProgramStateRef state,
191fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose                                              SVal cond, bool assumption) {
192fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose  return getCheckerManager().runCheckersForEvalAssume(state, cond, assumption);
19332a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek}
19432a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek
1958bef8238181a30e52dea380789a7e2d760eac532Ted Kremenekbool ExprEngine::wantsRegionChangeUpdate(ProgramStateRef state) {
196183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  return getCheckerManager().wantsRegionChangeUpdate(state);
197c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose}
198c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose
1998bef8238181a30e52dea380789a7e2d760eac532Ted KremenekProgramStateRef
2008bef8238181a30e52dea380789a7e2d760eac532Ted KremenekExprEngine::processRegionChanges(ProgramStateRef state,
20135bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek                            const StoreManager::InvalidatedSymbols *invalidated,
202537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                                 ArrayRef<const MemRegion *> Explicits,
20366c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks                                 ArrayRef<const MemRegion *> Regions,
204740d490593e0de8732a697c9f77b90ddd463863bJordan Rose                                 const CallEvent *Call) {
20535bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  return getCheckerManager().runCheckersForRegionChanges(state, invalidated,
20666c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks                                                      Explicits, Regions, Call);
207c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose}
208c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose
2098bef8238181a30e52dea380789a7e2d760eac532Ted Kremenekvoid ExprEngine::printState(raw_ostream &Out, ProgramStateRef State,
210dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose                            const char *NL, const char *Sep) {
211dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  getCheckerManager().runCheckersForPrintState(Out, State, NL, Sep);
212dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose}
213dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose
214e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenekvoid ExprEngine::processEndWorklist(bool hasWorkRemaining) {
21530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  getCheckerManager().runCheckersForEndAnalysis(G, BR, *this);
216ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek}
217ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek
218ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaksvoid ExprEngine::processCFGElement(const CFGElement E, ExplodedNode *Pred,
219ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks                                   unsigned StmtIdx, NodeBuilderContext *Ctx) {
22066c486f275531df6362b3511fc3af6563561801bTed Kremenek  currStmtIdx = StmtIdx;
22166c486f275531df6362b3511fc3af6563561801bTed Kremenek  currBldrCtx = Ctx;
222ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks
2239c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu  switch (E.getKind()) {
2243c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek    case CFGElement::Invalid:
2253c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek      llvm_unreachable("Unexpected CFGElement kind.");
2263c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek    case CFGElement::Statement:
227ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      ProcessStmt(const_cast<Stmt*>(E.getAs<CFGStmt>()->getStmt()), Pred);
2283c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek      return;
2293c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek    case CFGElement::Initializer:
230ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      ProcessInitializer(E.getAs<CFGInitializer>()->getInitializer(), Pred);
2313c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek      return;
2323c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek    case CFGElement::AutomaticObjectDtor:
2333c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek    case CFGElement::BaseDtor:
2343c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek    case CFGElement::MemberDtor:
2353c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek    case CFGElement::TemporaryDtor:
236ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      ProcessImplicitDtor(*E.getAs<CFGImplicitDtor>(), Pred);
2373c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek      return;
2389c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu  }
23966c486f275531df6362b3511fc3af6563561801bTed Kremenek  currBldrCtx = 0;
2409c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu}
2419c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu
242ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenekstatic bool shouldRemoveDeadBindings(AnalysisManager &AMgr,
243ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek                                     const CFGStmt S,
244ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek                                     const ExplodedNode *Pred,
245ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek                                     const LocationContext *LC) {
246ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek
247ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek  // Are we never purging state values?
248255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek  if (AMgr.options.AnalysisPurgeOpt == PurgeNone)
249ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek    return false;
250ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek
251ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek  // Is this the beginning of a basic block?
2529e9a3e612d57b583800d5f0e48bb28d4afbd8b84Ted Kremenek  if (isa<BlockEntrance>(Pred->getLocation()))
253ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek    return true;
254ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek
255ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek  // Is this on a non-expression?
256ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek  if (!isa<Expr>(S.getStmt()))
257ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek    return true;
258ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks
259ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks  // Run before processing a call.
2606062334cc388bce69fb3978c4ecb26c6485a5c2bJordan Rose  if (CallEvent::isCallStmt(S.getStmt()))
261ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks    return true;
262ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks
263ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek  // Is this an expression that is consumed by another expression?  If so,
264ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek  // postpone cleaning out the state.
265ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek  ParentMap &PM = LC->getAnalysisDeclContext()->getParentMap();
266ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek  return !PM.isConsumedExpr(cast<Expr>(S.getStmt()));
267ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek}
268ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek
2690b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaksvoid ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out,
2700b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                            const Stmt *ReferenceStmt,
2710b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                            const LocationContext *LC,
2720b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                            const Stmt *DiagnosticStmt,
2730b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                            ProgramPoint::Kind K) {
2740b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  assert((K == ProgramPoint::PreStmtPurgeDeadSymbolsKind ||
2750b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks          ReferenceStmt == 0) && "PreStmt is not generally supported by "
2760b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                                 "the SymbolReaper yet");
2770b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  NumRemoveDeadBindings++;
2780b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  CleanedState = Pred->getState();
2790b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  SymbolReaper SymReaper(LC, ReferenceStmt, SymMgr, getStoreManager());
2800b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks
2810b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  getCheckerManager().runCheckersForLiveSymbols(CleanedState, SymReaper);
2820b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks
2830b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  // Create a state in which dead bindings are removed from the environment
2840b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  // and the store. TODO: The function should just return new env and store,
2850b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  // not a new state.
2860b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  const StackFrameContext *SFC = LC->getCurrentStackFrame();
2870b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  CleanedState = StateMgr.removeDeadBindings(CleanedState, SFC, SymReaper);
288241677a13cc46647a8f5098b3e3239bd9480dca2Ted Kremenek
28977d7ef8d8a80ccb2ab3d25c80810571e3ab14ee4Ted Kremenek  // Process any special transfer function for dead symbols.
290f185cc1ac77a84139c603eee3473b88dcb839c68Anna Zaks  // A tag to track convenience transitions, which can be removed at cleanup.
291f185cc1ac77a84139c603eee3473b88dcb839c68Anna Zaks  static SimpleProgramPointTag cleanupTag("ExprEngine : Clean Node");
2926bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks  if (!SymReaper.hasDeadSymbols()) {
2936bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks    // Generate a CleanedNode that has the environment and store cleaned
2946bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks    // up. Since no symbols are dead, we can optimize and not clean out
2956bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks    // the constraint manager.
29666c486f275531df6362b3511fc3af6563561801bTed Kremenek    StmtNodeBuilder Bldr(Pred, Out, *currBldrCtx);
297fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    Bldr.generateNode(DiagnosticStmt, Pred, CleanedState, &cleanupTag, K);
2981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2996bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks  } else {
3006bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks    // Call checkers with the non-cleaned state so that they could query the
3016bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks    // values of the soon to be dead symbols.
302fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose    ExplodedNodeSet CheckedSet;
3030b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks    getCheckerManager().runCheckersForDeadSymbols(CheckedSet, Pred, SymReaper,
3040b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                                                  DiagnosticStmt, *this, K);
305183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
306fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose    // For each node in CheckedSet, generate CleanedNodes that have the
307fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose    // environment, the store, and the constraints cleaned up but have the
308fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose    // user-supplied states as the predecessors.
30966c486f275531df6362b3511fc3af6563561801bTed Kremenek    StmtNodeBuilder Bldr(CheckedSet, Out, *currBldrCtx);
310fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose    for (ExplodedNodeSet::const_iterator
311fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose          I = CheckedSet.begin(), E = CheckedSet.end(); I != E; ++I) {
3128bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek      ProgramStateRef CheckerState = (*I)->getState();
3136bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks
3146bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks      // The constraint manager has not been cleaned up yet, so clean up now.
3156bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks      CheckerState = getConstraintManager().removeDeadBindings(CheckerState,
3166bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks                                                               SymReaper);
3176bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks
3180b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      assert(StateMgr.haveEqualEnvironments(CheckerState, Pred->getState()) &&
3196bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks        "Checkers are not allowed to modify the Environment as a part of "
3206bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks        "checkDeadSymbols processing.");
3210b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      assert(StateMgr.haveEqualStores(CheckerState, Pred->getState()) &&
3226bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks        "Checkers are not allowed to modify the Store as a part of "
3236bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks        "checkDeadSymbols processing.");
3246bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks
3256bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks      // Create a state based on CleanedState with CheckerState GDM and
3266bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks      // generate a transition to that state.
3278bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek      ProgramStateRef CleanedCheckerSt =
3286bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks        StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState);
329fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose      Bldr.generateNode(DiagnosticStmt, *I, CleanedCheckerSt, &cleanupTag, K);
3306bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks    }
33177d7ef8d8a80ccb2ab3d25c80810571e3ab14ee4Ted Kremenek  }
3320b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks}
3330b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks
3340b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaksvoid ExprEngine::ProcessStmt(const CFGStmt S,
3350b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                             ExplodedNode *Pred) {
3360b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  // Reclaim any unnecessary nodes in the ExplodedGraph.
3370b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  G.reclaimRecentlyAllocatedNodes();
3380b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks
33966c486f275531df6362b3511fc3af6563561801bTed Kremenek  currStmt = S.getStmt();
3400b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
34166c486f275531df6362b3511fc3af6563561801bTed Kremenek                                currStmt->getLocStart(),
3420b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                                "Error evaluating statement");
3431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3440b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  // Remove dead bindings and symbols.
3450b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  EntryNode = Pred;
3460b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  ExplodedNodeSet CleanedStates;
3470b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  if (shouldRemoveDeadBindings(AMgr, S, Pred, EntryNode->getLocationContext())){
34866c486f275531df6362b3511fc3af6563561801bTed Kremenek    removeDead(EntryNode, CleanedStates, currStmt,
34966c486f275531df6362b3511fc3af6563561801bTed Kremenek               Pred->getLocationContext(), currStmt);
3500b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  } else
3510b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks    CleanedStates.Add(EntryNode);
3520b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks
3530b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  // Visit the statement.
354dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks  ExplodedNodeSet Dst;
3550b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  for (ExplodedNodeSet::iterator I = CleanedStates.begin(),
3560b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                                 E = CleanedStates.end(); I != E; ++I) {
357dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks    ExplodedNodeSet DstI;
3581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Visit the statement.
35966c486f275531df6362b3511fc3af6563561801bTed Kremenek    Visit(currStmt, *I, DstI);
360dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks    Dst.insert(DstI);
361ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks  }
362ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks
363dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks  // Enqueue the new nodes onto the work list.
36466c486f275531df6362b3511fc3af6563561801bTed Kremenek  Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
3651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
366e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek  // NULL out these variables to cleanup.
367846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek  CleanedState = NULL;
368846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek  EntryNode = NULL;
36966c486f275531df6362b3511fc3af6563561801bTed Kremenek  currStmt = 0;
370e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek}
371e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek
372d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessInitializer(const CFGInitializer Init,
373056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks                                    ExplodedNode *Pred) {
374cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt  const CXXCtorInitializer *BMI = Init.getInitializer();
375563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose
376563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
377563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose                                BMI->getSourceLocation(),
378563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose                                "Error evaluating initializer");
379563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose
38066c486f275531df6362b3511fc3af6563561801bTed Kremenek  // We don't set EntryNode and currStmt. And we don't clean up state.
381056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks  const StackFrameContext *stackFrame =
382056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks                           cast<StackFrameContext>(Pred->getLocationContext());
383056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks  const CXXConstructorDecl *decl =
384056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks                           cast<CXXConstructorDecl>(stackFrame->getDecl());
3853682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose
3863682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  ProgramStateRef State = Pred->getState();
3873a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  SVal thisVal = State->getSVal(svalBuilder.getCXXThis(decl, stackFrame));
3889dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu
3893682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  PostInitializer PP(BMI, stackFrame);
3903682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  ExplodedNodeSet Tmp(Pred);
3913682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose
3923a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  // Evaluate the initializer, if necessary
39300eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet  if (BMI->isAnyMemberInitializer()) {
3943a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose    // Constructors build the object directly in the field,
3953a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose    // but non-objects must be copied in from the initializer.
3963682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose    const Expr *Init = BMI->getInit();
3973682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose    if (!isa<CXXConstructExpr>(Init)) {
3983a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose      SVal FieldLoc;
3993a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose      if (BMI->isIndirectMemberInitializer())
4003a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose        FieldLoc = State->getLValue(BMI->getIndirectMember(), thisVal);
4013a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose      else
4023a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose        FieldLoc = State->getLValue(BMI->getMember(), thisVal);
4033a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose
4043a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose      SVal InitVal = State->getSVal(BMI->getInit(), stackFrame);
4053682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose
4063682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose      Tmp.clear();
4073682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose      evalBind(Tmp, Init, Pred, FieldLoc, InitVal, /*isInit=*/true, &PP);
4083a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose    }
409056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks  } else {
410563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose    assert(BMI->isBaseInitializer() || BMI->isDelegatingInitializer());
411888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose    // We already did all the work when visiting the CXXConstructExpr.
412056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks  }
413dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks
4143682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  // Construct PostInitializer nodes whether the state changed or not,
4153a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  // so that the diagnostics don't get confused.
4163682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  ExplodedNodeSet Dst;
4173682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  NodeBuilder Bldr(Tmp, Dst, *currBldrCtx);
4183682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) {
4193682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose    ExplodedNode *N = *I;
4203682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose    Bldr.generateNode(PP, N->getState(), N);
4213682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  }
4223a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose
423dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks  // Enqueue the new nodes onto the work list.
42466c486f275531df6362b3511fc3af6563561801bTed Kremenek  Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
4259c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu}
4269c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu
427d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D,
428ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks                                     ExplodedNode *Pred) {
429ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks  ExplodedNodeSet Dst;
4303c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek  switch (D.getKind()) {
4314ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu  case CFGElement::AutomaticObjectDtor:
432056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks    ProcessAutomaticObjDtor(cast<CFGAutomaticObjDtor>(D), Pred, Dst);
4334ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu    break;
4344ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu  case CFGElement::BaseDtor:
435056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks    ProcessBaseDtor(cast<CFGBaseDtor>(D), Pred, Dst);
4364ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu    break;
4374ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu  case CFGElement::MemberDtor:
438056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks    ProcessMemberDtor(cast<CFGMemberDtor>(D), Pred, Dst);
4394ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu    break;
4404ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu  case CFGElement::TemporaryDtor:
441056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks    ProcessTemporaryDtor(cast<CFGTemporaryDtor>(D), Pred, Dst);
4424ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu    break;
4434ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu  default:
4444ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu    llvm_unreachable("Unexpected dtor kind.");
4454ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu  }
446ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks
447dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks  // Enqueue the new nodes onto the work list.
44866c486f275531df6362b3511fc3af6563561801bTed Kremenek  Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
4494ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu}
4504ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu
451056c4b46335a3bd2612414735d5749ee159c0165Anna Zaksvoid ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor,
452056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks                                         ExplodedNode *Pred,
453056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks                                         ExplodedNodeSet &Dst) {
4548bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef state = Pred->getState();
455056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks  const VarDecl *varDecl = Dtor.getVarDecl();
4562210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu
4572210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu  QualType varType = varDecl->getType();
4582210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu
4592210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu  if (const ReferenceType *refType = varType->getAs<ReferenceType>())
4602210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu    varType = refType->getPointeeType();
4612210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu
462056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks  Loc dest = state->getLValue(varDecl, Pred->getLocationContext());
463b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu
464888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  VisitCXXDestructor(varType, cast<loc::MemRegionVal>(dest).getRegion(),
465200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose                     Dtor.getTriggerStmt(), /*IsBase=*/false, Pred, Dst);
4664ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu}
4674ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu
468d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessBaseDtor(const CFGBaseDtor D,
469888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose                                 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
470888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  const LocationContext *LCtx = Pred->getLocationContext();
471888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  ProgramStateRef State = Pred->getState();
472888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose
473888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
474888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor,
475888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose                                            LCtx->getCurrentStackFrame());
476888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  SVal ThisVal = Pred->getState()->getSVal(ThisPtr);
477888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose
478888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  // Create the base object region.
479888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  QualType BaseTy = D.getBaseSpecifier()->getType();
480888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, BaseTy);
481888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose
482888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  VisitCXXDestructor(BaseTy, cast<loc::MemRegionVal>(BaseVal).getRegion(),
483200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose                     CurDtor->getBody(), /*IsBase=*/true, Pred, Dst);
484888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose}
4854ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu
486d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessMemberDtor(const CFGMemberDtor D,
4873a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose                                   ExplodedNode *Pred, ExplodedNodeSet &Dst) {
4883a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  const FieldDecl *Member = D.getFieldDecl();
4893a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  ProgramStateRef State = Pred->getState();
4903a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  const LocationContext *LCtx = Pred->getLocationContext();
4913a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose
4923a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
4933a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  Loc ThisVal = getSValBuilder().getCXXThis(CurDtor,
4943a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose                                            LCtx->getCurrentStackFrame());
4953a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  SVal FieldVal = State->getLValue(Member, cast<Loc>(State->getSVal(ThisVal)));
4963a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose
4973a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  VisitCXXDestructor(Member->getType(),
4983a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose                     cast<loc::MemRegionVal>(FieldVal).getRegion(),
499200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose                     CurDtor->getBody(), /*IsBase=*/false, Pred, Dst);
5003a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose}
5014ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu
502d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessTemporaryDtor(const CFGTemporaryDtor D,
503056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks                                      ExplodedNode *Pred,
504056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks                                      ExplodedNodeSet &Dst) {}
5059c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu
50648b6247804eacc262cc5508e0fbb74ed819fbb6eJordan Rosevoid ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
5076889679d72859960e0fc8d1080487f63c4df1e0aAnna Zaks                       ExplodedNodeSet &DstTop) {
5080bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
5090bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek                                S->getLocStart(),
5100bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek                                "Error evaluating statement");
5116889679d72859960e0fc8d1080487f63c4df1e0aAnna Zaks  ExplodedNodeSet Dst;
51266c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(Pred, DstTop, *currBldrCtx);
5130bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek
514f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall  // Expressions to ignore.
515f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall  if (const Expr *Ex = dyn_cast<Expr>(S))
516892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    S = Ex->IgnoreParens();
517f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall
518e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek  // FIXME: add metadata to the CFG so that we can disable
519e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek  //  this check when we KNOW that there is no block-level subexpression.
520e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek  //  The motivation is that this check requires a hashtable lookup.
5211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
52266c486f275531df6362b3511fc3af6563561801bTed Kremenek  if (S != currStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(S))
523e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    return;
5241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
525e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek  switch (S->getStmtClass()) {
526f85e193739c953358c865005855253af4f68a497John McCall    // C++ and ARC stuff we don't support yet.
527f85e193739c953358c865005855253af4f68a497John McCall    case Expr::ObjCIndirectCopyRestoreExprClass:
5281b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::CXXDependentScopeMemberExprClass:
5291b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::CXXPseudoDestructorExprClass:
5301b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::CXXTryStmtClass:
5311b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::CXXTypeidExprClass:
5329be88403e965cc49af76c9d33d818781d44b333eFrancois Pichet    case Stmt::CXXUuidofExprClass:
533c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek    case Stmt::CXXUnresolvedConstructExprClass:
5341b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::DependentScopeDeclRefExprClass:
5351b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::UnaryTypeTraitExprClass:
5366ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet    case Stmt::BinaryTypeTraitExprClass:
5374ca8ac2e61c37ddadf37024af86f3e1019af8532Douglas Gregor    case Stmt::TypeTraitExprClass:
53821ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley    case Stmt::ArrayTypeTraitExprClass:
539552622067dc45013d240f73952fece703f5e63bdJohn Wiegley    case Stmt::ExpressionTraitExprClass:
5401b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::UnresolvedLookupExprClass:
541c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek    case Stmt::UnresolvedMemberExprClass:
5426b219d082434394c1ac401390ec1d1967727815aSebastian Redl    case Stmt::CXXNoexceptExprClass:
543be230c36e32142cbdcdbe9c97511d097beeecbabDouglas Gregor    case Stmt::PackExpansionExprClass:
544c7793c73ba8a343de3f2552d984851985a46f159Douglas Gregor    case Stmt::SubstNonTypeTemplateParmPackExprClass:
5459a4db032ecd991626d236a502e770126db32bd31Richard Smith    case Stmt::FunctionParmPackExprClass:
54628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    case Stmt::SEHTryStmtClass:
54728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    case Stmt::SEHExceptStmtClass:
54801d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor    case Stmt::LambdaExprClass:
549ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks    case Stmt::SEHFinallyStmtClass: {
550fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose      const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState());
55166c486f275531df6362b3511fc3af6563561801bTed Kremenek      Engine.addAbortedBlock(node, currBldrCtx->getBlock());
552c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek      break;
553c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek    }
5545fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek
555f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    case Stmt::ParenExprClass:
556f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall      llvm_unreachable("ParenExprs already handled.");
557f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne    case Stmt::GenericSelectionExprClass:
558f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne      llvm_unreachable("GenericSelectionExprs already handled.");
5591b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    // Cases that should never be evaluated simply because they shouldn't
5601b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    // appear in the CFG.
5611b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::BreakStmtClass:
5621b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::CaseStmtClass:
5631b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::CompoundStmtClass:
5641b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ContinueStmtClass:
56546eaf7789a1059a7b42b7dbd183150c72df5738fTed Kremenek    case Stmt::CXXForRangeStmtClass:
5661b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::DefaultStmtClass:
5671b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::DoStmtClass:
568d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek    case Stmt::ForStmtClass:
5691b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::GotoStmtClass:
570d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek    case Stmt::IfStmtClass:
5711b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::IndirectGotoStmtClass:
5721b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::LabelStmtClass:
573534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    case Stmt::AttributedStmtClass:
5741b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::NoStmtClass:
5751b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::NullStmtClass:
576d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek    case Stmt::SwitchStmtClass:
577d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek    case Stmt::WhileStmtClass:
578ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor    case Expr::MSDependentExistsStmtClass:
5791b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek      llvm_unreachable("Stmt should not be in analyzer evaluation loop");
5801b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek
5814ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose    case Stmt::ObjCSubscriptRefExprClass:
5824ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose    case Stmt::ObjCPropertyRefExprClass:
5834ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose      llvm_unreachable("These are handled by PseudoObjectExpr");
5844ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose
5858ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek    case Stmt::GNUNullExprClass: {
5868f08426e6f54ed20b959018f24dbea106a00b4adJordy Rose      // GNU __null is a pointer-width integer, not an actual pointer.
5878bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek      ProgramStateRef state = Pred->getState();
5885eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek      state = state->BindExpr(S, Pred->getLocationContext(),
5895eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                              svalBuilder.makeIntValWithPtrWidth(0, false));
590ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.generateNode(S, Pred, state);
5918ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek      break;
5928ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek    }
5938ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek
5944beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek    case Stmt::ObjCAtSynchronizedStmtClass:
595ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
5964beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek      VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S), Pred, Dst);
597ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
5984beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek      break;
5994beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek
600ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks    case Stmt::ExprWithCleanupsClass:
601e711d7e7875920fee4180a26bfc67d67f0f71a2cErik Verbruggen      // Handled due to fully linearised CFG.
602f85e193739c953358c865005855253af4f68a497John McCall      break;
603f85e193739c953358c865005855253af4f68a497John McCall
6041b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    // Cases not handled yet; but will handle some day.
6051b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::DesignatedInitExprClass:
6061b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ExtVectorElementExprClass:
6071b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ImaginaryLiteralClass:
6081b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ObjCAtCatchStmtClass:
6091b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ObjCAtFinallyStmtClass:
6101b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ObjCAtTryStmtClass:
611f85e193739c953358c865005855253af4f68a497John McCall    case Stmt::ObjCAutoreleasePoolStmtClass:
6121b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ObjCEncodeExprClass:
6131b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ObjCIsaExprClass:
6141b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ObjCProtocolExprClass:
6151b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ObjCSelectorExprClass:
6161b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ParenListExprClass:
6171b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::PredefinedExprClass:
6181b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ShuffleVectorExprClass:
6191b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::VAArgExprClass:
620e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne    case Stmt::CUDAKernelCallExprClass:
62156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall    case Stmt::OpaqueValueExprClass:
62261eee0ca33b29e102f11bab77c8b74cc00e2392bTanya Lattner    case Stmt::AsTypeExprClass:
623276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman    case Stmt::AtomicExprClass:
624337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek      // Fall through.
6251b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek
6261b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    // Cases we intentionally don't evaluate, since they don't need
6271b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    // to be explicitly evaluated.
628bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu    case Stmt::AddrLabelExprClass:
629bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu    case Stmt::IntegerLiteralClass:
630bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu    case Stmt::CharacterLiteralClass:
631c319c585c0d5899cba0dca2272e6e4909c8b9f16Ted Kremenek    case Stmt::ImplicitValueInitExprClass:
632c319c585c0d5899cba0dca2272e6e4909c8b9f16Ted Kremenek    case Stmt::CXXScalarValueInitExprClass:
633477323d58a0de352c6a61e08b5a83127c4adc904Zhongxing Xu    case Stmt::CXXBoolLiteralExprClass:
6341a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek    case Stmt::ObjCBoolLiteralExprClass:
635bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu    case Stmt::FloatingLiteralClass:
636f901a7de97f46ba2b1ff153f9fb83d00dc37cfcfDouglas Gregor    case Stmt::SizeOfPackExprClass:
637e739a29c62c67eaec0af5c4d5c75f9e8f11228bdTed Kremenek    case Stmt::StringLiteralClass:
638e739a29c62c67eaec0af5c4d5c75f9e8f11228bdTed Kremenek    case Stmt::ObjCStringLiteralClass:
639cc2c4b293d8590346f26b7ecc16d299226b8794fTed Kremenek    case Stmt::CXXBindTemporaryExprClass:
640b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose    case Stmt::CXXDefaultArgExprClass:
64169a0e5021c5c49a34aa25cd89b1e613a52097e65Jordan Rose    case Stmt::SubstNonTypeTemplateParmExprClass:
642bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek    case Stmt::CXXNullPtrLiteralExprClass: {
643bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek      Bldr.takeNodes(Pred);
644bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek      ExplodedNodeSet preVisit;
645bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek      getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
646bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek      getCheckerManager().runCheckersForPostStmt(Dst, preVisit, S, *this);
647bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek      Bldr.addNodes(Dst);
648e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
649bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek    }
6501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6511a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek    case Expr::ObjCArrayLiteralClass:
65270fdbc366da85880aae5baebd3351e993ca05603Jordy Rose    case Expr::ObjCDictionaryLiteralClass:
65370fdbc366da85880aae5baebd3351e993ca05603Jordy Rose      // FIXME: explicitly model with a region and the actual contents
65470fdbc366da85880aae5baebd3351e993ca05603Jordy Rose      // of the container.  For now, conjure a symbol.
65570fdbc366da85880aae5baebd3351e993ca05603Jordy Rose    case Expr::ObjCBoxedExprClass: {
6561a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      Bldr.takeNodes(Pred);
6571a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek
6581a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      ExplodedNodeSet preVisit;
6591a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
6601a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek
6611a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      ExplodedNodeSet Tmp;
66266c486f275531df6362b3511fc3af6563561801bTed Kremenek      StmtNodeBuilder Bldr2(preVisit, Tmp, *currBldrCtx);
6631a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek
66470fdbc366da85880aae5baebd3351e993ca05603Jordy Rose      const Expr *Ex = cast<Expr>(S);
66570fdbc366da85880aae5baebd3351e993ca05603Jordy Rose      QualType resultType = Ex->getType();
66670fdbc366da85880aae5baebd3351e993ca05603Jordy Rose
6671a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      for (ExplodedNodeSet::iterator it = preVisit.begin(), et = preVisit.end();
6681a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek           it != et; ++it) {
6691a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek        ExplodedNode *N = *it;
6701a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek        const LocationContext *LCtx = N->getLocationContext();
6713b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek        SVal result = svalBuilder.conjureSymbolVal(0, Ex, LCtx, resultType,
67266c486f275531df6362b3511fc3af6563561801bTed Kremenek                                                   currBldrCtx->blockCount());
6731a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek        ProgramStateRef state = N->getState()->BindExpr(Ex, LCtx, result);
6741a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek        Bldr2.generateNode(S, N, state);
6751a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      }
6761a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek
6771a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
6781a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      Bldr.addNodes(Dst);
6791a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      break;
6801a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek    }
6811a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek
682540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek    case Stmt::ArraySubscriptExprClass:
683ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
684892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      VisitLvalArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst);
685ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
686540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek      break;
6871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
688df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier    case Stmt::GCCAsmStmtClass:
689ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
690df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier      VisitGCCAsmStmt(cast<GCCAsmStmt>(S), Pred, Dst);
691ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
692e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
693b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
6948cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier    case Stmt::MSAsmStmtClass:
6958cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier      Bldr.takeNodes(Pred);
6968cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier      VisitMSAsmStmt(cast<MSAsmStmt>(S), Pred, Dst);
6978cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier      Bldr.addNodes(Dst);
6988cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier      break;
6998cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier
700c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek    case Stmt::BlockExprClass:
701ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
702c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek      VisitBlockExpr(cast<BlockExpr>(S), Pred, Dst);
703ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
704c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek      break;
705c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek
706e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    case Stmt::BinaryOperatorClass: {
70703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu      const BinaryOperator* B = cast<BinaryOperator>(S);
708e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      if (B->isLogicalOp()) {
709ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks        Bldr.takeNodes(Pred);
710e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek        VisitLogicalExpr(B, Pred, Dst);
711ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks        Bldr.addNodes(Dst);
712e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek        break;
713e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      }
7142de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      else if (B->getOpcode() == BO_Comma) {
7158bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek        ProgramStateRef state = Pred->getState();
716ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks        Bldr.generateNode(B, Pred,
7175eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                          state->BindExpr(B, Pred->getLocationContext(),
7185eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                          state->getSVal(B->getRHS(),
7195eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                                  Pred->getLocationContext())));
720e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek        break;
721e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      }
72206fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek
723ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
724ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks
7250caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek      if (AMgr.options.eagerlyAssumeBinOpBifurcation &&
726bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu          (B->isRelationalOp() || B->isEqualityOp())) {
727031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu        ExplodedNodeSet Tmp;
728892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek        VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp);
7290caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek        evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, cast<Expr>(S));
73048af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek      }
73148af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek      else
732892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek        VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
73348af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek
734ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
735e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
736e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    }
73706fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek
738f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose    case Stmt::CXXOperatorCallExprClass: {
739f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose      const CXXOperatorCallExpr *OCE = cast<CXXOperatorCallExpr>(S);
740f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
741f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose      // For instance method operators, make sure the 'this' argument has a
742f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose      // valid region.
743f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose      const Decl *Callee = OCE->getCalleeDecl();
744f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose      if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
745f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose        if (MD->isInstance()) {
746f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose          ProgramStateRef State = Pred->getState();
747f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose          const LocationContext *LCtx = Pred->getLocationContext();
748f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose          ProgramStateRef NewState =
749f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose            createTemporaryRegionIfNeeded(State, LCtx, OCE->getArg(0));
750f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose          if (NewState != State)
751f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose            Pred = Bldr.generateNode(OCE, Pred, NewState, /*Tag=*/0,
752f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose                                     ProgramPoint::PreStmtKind);
753f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose        }
754f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose      }
755f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose      // FALLTHROUGH
756f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose    }
757b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek    case Stmt::CallExprClass:
7589fcce65e7e1307b5b8da9be13e4092d6bb94dc1dRichard Smith    case Stmt::CXXMemberCallExprClass:
7599fcce65e7e1307b5b8da9be13e4092d6bb94dc1dRichard Smith    case Stmt::UserDefinedLiteralClass: {
760ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
761b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek      VisitCallExpr(cast<CallExpr>(S), Pred, Dst);
762ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
76306fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek      break;
764e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    }
765337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek
766337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek    case Stmt::CXXCatchStmtClass: {
767337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek      Bldr.takeNodes(Pred);
768337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek      VisitCXXCatchStmt(cast<CXXCatchStmt>(S), Pred, Dst);
769337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek      Bldr.addNodes(Dst);
770337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek      break;
771337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek    }
77206fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek
773744f1cd66bb6747ea71fbf1172698e7bf35ec88dTed Kremenek    case Stmt::CXXTemporaryObjectExprClass:
774888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose    case Stmt::CXXConstructExprClass: {
775ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
776888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose      VisitCXXConstructExpr(cast<CXXConstructExpr>(S), Pred, Dst);
777ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
7787ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu      break;
7797ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu    }
7807ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu
781856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu    case Stmt::CXXNewExprClass: {
782ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
78303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu      const CXXNewExpr *NE = cast<CXXNewExpr>(S);
784856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu      VisitCXXNewExpr(NE, Pred, Dst);
785ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
786856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu      break;
787856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu    }
788856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu
7896b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu    case Stmt::CXXDeleteExprClass: {
790ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
79103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu      const CXXDeleteExpr *CDE = cast<CXXDeleteExpr>(S);
7926b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu      VisitCXXDeleteExpr(CDE, Pred, Dst);
793ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
7946b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu      break;
7956b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu    }
796e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      // FIXME: ChooseExpr is really a constant.  We need to fix
797e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      //        the CFG do not model them as explicit control-flow.
7981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
799e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    case Stmt::ChooseExprClass: { // __builtin_choose_expr
800ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
8019c378f705405d37f49795d5e915989de774fe11fTed Kremenek      const ChooseExpr *C = cast<ChooseExpr>(S);
802e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
803ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
804e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
805e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    }
8061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
807e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    case Stmt::CompoundAssignOperatorClass:
808ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
809892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
810ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
811e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
812f22679e3e5d5f5754931952e58112b4c863a4137Zhongxing Xu
813f22679e3e5d5f5754931952e58112b4c863a4137Zhongxing Xu    case Stmt::CompoundLiteralExprClass:
814ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
815892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst);
816ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
817f22679e3e5d5f5754931952e58112b4c863a4137Zhongxing Xu      break;
8181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
81956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall    case Stmt::BinaryConditionalOperatorClass:
820e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    case Stmt::ConditionalOperatorClass: { // '?' operator
821ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
82256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      const AbstractConditionalOperator *C
82356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        = cast<AbstractConditionalOperator>(S);
82456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      VisitGuardedExpr(C, C->getTrueExpr(), C->getFalseExpr(), Pred, Dst);
825ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
826e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
827e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    }
8281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
829bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu    case Stmt::CXXThisExprClass:
830ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
831bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu      VisitCXXThisExpr(cast<CXXThisExpr>(S), Pred, Dst);
832ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
833bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu      break;
834bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu
835892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    case Stmt::DeclRefExprClass: {
836ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
837892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      const DeclRefExpr *DE = cast<DeclRefExpr>(S);
838892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      VisitCommonDeclRefExpr(DE, DE->getDecl(), Pred, Dst);
839ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
840e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
841892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    }
8421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
843e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    case Stmt::DeclStmtClass:
844ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
845e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
846ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
847e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
8481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8490835a3cdeefe714b4959d31127ea155e56393125Argyrios Kyrtzidis    case Stmt::ImplicitCastExprClass:
8500d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu    case Stmt::CStyleCastExprClass:
8510d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu    case Stmt::CXXStaticCastExprClass:
8520d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu    case Stmt::CXXDynamicCastExprClass:
8530d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu    case Stmt::CXXReinterpretCastExprClass:
8540d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu    case Stmt::CXXConstCastExprClass:
855f85e193739c953358c865005855253af4f68a497John McCall    case Stmt::CXXFunctionalCastExprClass:
856f85e193739c953358c865005855253af4f68a497John McCall    case Stmt::ObjCBridgedCastExprClass: {
857ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
8589c378f705405d37f49795d5e915989de774fe11fTed Kremenek      const CastExpr *C = cast<CastExpr>(S);
859f85e193739c953358c865005855253af4f68a497John McCall      // Handle the previsit checks.
860f85e193739c953358c865005855253af4f68a497John McCall      ExplodedNodeSet dstPrevisit;
861f85e193739c953358c865005855253af4f68a497John McCall      getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, C, *this);
862f85e193739c953358c865005855253af4f68a497John McCall
863f85e193739c953358c865005855253af4f68a497John McCall      // Handle the expression itself.
864f85e193739c953358c865005855253af4f68a497John McCall      ExplodedNodeSet dstExpr;
865f85e193739c953358c865005855253af4f68a497John McCall      for (ExplodedNodeSet::iterator i = dstPrevisit.begin(),
866f85e193739c953358c865005855253af4f68a497John McCall                                     e = dstPrevisit.end(); i != e ; ++i) {
867f85e193739c953358c865005855253af4f68a497John McCall        VisitCast(C, C->getSubExpr(), *i, dstExpr);
868f85e193739c953358c865005855253af4f68a497John McCall      }
869f85e193739c953358c865005855253af4f68a497John McCall
870f85e193739c953358c865005855253af4f68a497John McCall      // Handle the postvisit checks.
871f85e193739c953358c865005855253af4f68a497John McCall      getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, C, *this);
872ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
873e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
874e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    }
875b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
87603e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor    case Expr::MaterializeTemporaryExprClass: {
877ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
878c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose      const MaterializeTemporaryExpr *MTE = cast<MaterializeTemporaryExpr>(S);
879c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose      CreateCXXTemporaryObject(MTE, Pred, Dst);
880ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
88103e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor      break;
88203e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor    }
88303e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor
884c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu    case Stmt::InitListExprClass:
885ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
886c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu      VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst);
887ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
888c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu      break;
8891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
89097ed4f68f5dba3e21e7a490ef0f9ffd3bfead7f8Ted Kremenek    case Stmt::MemberExprClass:
891ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
892892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst);
893ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
894469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek      break;
895ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks
89697ed4f68f5dba3e21e7a490ef0f9ffd3bfead7f8Ted Kremenek    case Stmt::ObjCIvarRefExprClass:
897ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
898892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      VisitLvalObjCIvarRefExpr(cast<ObjCIvarRefExpr>(S), Pred, Dst);
899ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
90097ed4f68f5dba3e21e7a490ef0f9ffd3bfead7f8Ted Kremenek      break;
901af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek
902af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek    case Stmt::ObjCForCollectionStmtClass:
903ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
904af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek      VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S), Pred, Dst);
905ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
906af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek      break;
9071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
908d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose    case Stmt::ObjCMessageExprClass:
909ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
910d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose      VisitObjCMessage(cast<ObjCMessageExpr>(S), Pred, Dst);
911ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
912e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
9131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
914c32a453e40b2c8878fed10512fb2f570b7aba576Jordan Rose    case Stmt::ObjCAtThrowStmtClass:
915c32a453e40b2c8878fed10512fb2f570b7aba576Jordan Rose    case Stmt::CXXThrowExprClass:
916bbfd07a0c94f659beaf74316029ef73769cefb81Ted Kremenek      // FIXME: This is not complete.  We basically treat @throw as
917bbfd07a0c94f659beaf74316029ef73769cefb81Ted Kremenek      // an abort.
918fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose      Bldr.generateSink(S, Pred, Pred->getState());
919bbfd07a0c94f659beaf74316029ef73769cefb81Ted Kremenek      break;
9201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9211b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    case Stmt::ReturnStmtClass:
922ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
9231b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek      VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst);
924ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
9251b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek      break;
9261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9278ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    case Stmt::OffsetOfExprClass:
928ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
9298ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Pred, Dst);
930ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
9318ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      break;
9328ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
933f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne    case Stmt::UnaryExprOrTypeTraitExprClass:
934ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
935f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne      VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S),
936f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne                                    Pred, Dst);
937ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
938e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
9391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
940e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    case Stmt::StmtExprClass: {
9419c378f705405d37f49795d5e915989de774fe11fTed Kremenek      const StmtExpr *SE = cast<StmtExpr>(S);
942a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek
943a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek      if (SE->getSubStmt()->body_empty()) {
944a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek        // Empty statement expression.
945a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek        assert(SE->getType() == getContext().VoidTy
946a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek               && "Empty statement expression must have void type.");
947a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek        break;
948a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek      }
9491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9509c378f705405d37f49795d5e915989de774fe11fTed Kremenek      if (Expr *LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
9518bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek        ProgramStateRef state = Pred->getState();
952ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks        Bldr.generateNode(SE, Pred,
9535eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                          state->BindExpr(SE, Pred->getLocationContext(),
9545eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                          state->getSVal(LastExpr,
9555eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                                  Pred->getLocationContext())));
956a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek      }
957e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
958e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    }
9596987c7b74146b9658b1925c5981f8b0cd0672b55Zhongxing Xu
96072374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek    case Stmt::UnaryOperatorClass: {
961ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
96203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu      const UnaryOperator *U = cast<UnaryOperator>(S);
9630caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek      if (AMgr.options.eagerlyAssumeBinOpBifurcation && (U->getOpcode() == UO_LNot)) {
964031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu        ExplodedNodeSet Tmp;
965892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek        VisitUnaryOperator(U, Pred, Tmp);
9660caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek        evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, U);
96772374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek      }
96872374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek      else
969892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek        VisitUnaryOperator(U, Pred, Dst);
970ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
9711b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek      break;
97272374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek    }
9734b9c2d235fb9449e249d74f48ecfec601650de93John McCall
9744b9c2d235fb9449e249d74f48ecfec601650de93John McCall    case Stmt::PseudoObjectExprClass: {
9754b9c2d235fb9449e249d74f48ecfec601650de93John McCall      Bldr.takeNodes(Pred);
9768bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek      ProgramStateRef state = Pred->getState();
9774b9c2d235fb9449e249d74f48ecfec601650de93John McCall      const PseudoObjectExpr *PE = cast<PseudoObjectExpr>(S);
9784b9c2d235fb9449e249d74f48ecfec601650de93John McCall      if (const Expr *Result = PE->getResultExpr()) {
9795eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek        SVal V = state->getSVal(Result, Pred->getLocationContext());
9805eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek        Bldr.generateNode(S, Pred,
9815eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                          state->BindExpr(S, Pred->getLocationContext(), V));
9824b9c2d235fb9449e249d74f48ecfec601650de93John McCall      }
9834b9c2d235fb9449e249d74f48ecfec601650de93John McCall      else
9845eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek        Bldr.generateNode(S, Pred,
9855eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                          state->BindExpr(S, Pred->getLocationContext(),
9865eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                                   UnknownVal()));
9874b9c2d235fb9449e249d74f48ecfec601650de93John McCall
9884b9c2d235fb9449e249d74f48ecfec601650de93John McCall      Bldr.addNodes(Dst);
9894b9c2d235fb9449e249d74f48ecfec601650de93John McCall      break;
9904b9c2d235fb9449e249d74f48ecfec601650de93John McCall    }
9911b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  }
9921b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek}
9931b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
9945903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaksbool ExprEngine::replayWithoutInlining(ExplodedNode *N,
9955903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks                                       const LocationContext *CalleeLC) {
9965903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  const StackFrameContext *CalleeSF = CalleeLC->getCurrentStackFrame();
9975903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  const StackFrameContext *CallerSF = CalleeSF->getParent()->getCurrentStackFrame();
9985903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  assert(CalleeSF && CallerSF);
9995903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  ExplodedNode *BeforeProcessingCall = 0;
100028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose  const Stmt *CE = CalleeSF->getCallSite();
10015903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
10025903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  // Find the first node before we started processing the call expression.
10035903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  while (N) {
10045903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    ProgramPoint L = N->getLocation();
10055903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    BeforeProcessingCall = N;
10065903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    N = N->pred_empty() ? NULL : *(N->pred_begin());
10075903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
10085903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    // Skip the nodes corresponding to the inlined code.
10095903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    if (L.getLocationContext()->getCurrentStackFrame() != CallerSF)
10105903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      continue;
10115903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    // We reached the caller. Find the node right before we started
101228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose    // processing the call.
10130b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks    if (L.isPurgeKind())
10145903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      continue;
101528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose    if (isa<PreImplicitCall>(&L))
101628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose      continue;
1017852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose    if (isa<CallEnter>(&L))
1018852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose      continue;
10195903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    if (const StmtPoint *SP = dyn_cast<StmtPoint>(&L))
102028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose      if (SP->getStmt() == CE)
10215903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks        continue;
10225903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    break;
10235903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  }
10245903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
1025253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks  if (!BeforeProcessingCall)
10265903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    return false;
10275903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
10285903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  // TODO: Clean up the unneeded nodes.
10295903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
10305903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  // Build an Epsilon node from which we will restart the analyzes.
103128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose  // Note that CE is permitted to be NULL!
10325903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  ProgramPoint NewNodeLoc =
10335903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks               EpsilonPoint(BeforeProcessingCall->getLocationContext(), CE);
10345903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  // Add the special flag to GDM to signal retrying with no inlining.
10355903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  // Note, changing the state ensures that we are not going to cache out.
10365903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  ProgramStateRef NewNodeState = BeforeProcessingCall->getState();
10375903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  NewNodeState = NewNodeState->set<ReplayWithoutInlining>((void*)CE);
10385903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
10395903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  // Make the new node a successor of BeforeProcessingCall.
10405903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  bool IsNew = false;
10415903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  ExplodedNode *NewNode = G.getNode(NewNodeLoc, NewNodeState, false, &IsNew);
1042253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks  // We cached out at this point. Caching out is common due to us backtracking
1043253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks  // from the inlined function, which might spawn several paths.
1044253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks  if (!IsNew)
1045253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks    return true;
1046253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks
10475903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  NewNode->addPredecessor(BeforeProcessingCall, G);
10485903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
10495903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  // Add the new node to the work list.
10505903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  Engine.enqueueStmtNode(NewNode, CalleeSF->getCallSiteBlock(),
10515903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks                                  CalleeSF->getIndex());
10525903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  NumTimesRetriedWithoutInlining++;
10535903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  return true;
10545903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks}
10555903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
1056c03a39e16762627b421247b12a2658be630a3300Anna Zaks/// Block entrance.  (Update counters).
1057253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaksvoid ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
1058253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks                                         NodeBuilderWithSinks &nodeBuilder) {
105927c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek
106027c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek  // FIXME: Refactor this into a checker.
1061c03a39e16762627b421247b12a2658be630a3300Anna Zaks  ExplodedNode *pred = nodeBuilder.getContext().getPred();
106227c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek
10632fa9d72d4d23ccdcd4137946e5ebafac7a04f04cTed Kremenek  if (nodeBuilder.getContext().blockCount() >= AMgr.options.maxBlockVisitOnPath) {
1064ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek    static SimpleProgramPointTag tag("ExprEngine : Block count exceeded");
1065253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks    const ExplodedNode *Sink =
1066fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose                   nodeBuilder.generateSink(pred->getState(), pred, &tag);
1067749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks
1068749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks    // Check if we stopped at the top level function or not.
1069749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks    // Root node should have the location context of the top most function.
10705903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    const LocationContext *CalleeLC = pred->getLocation().getLocationContext();
10713bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks    const LocationContext *CalleeSF = CalleeLC->getCurrentStackFrame();
10725903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    const LocationContext *RootLC =
10735903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks                        (*G.roots_begin())->getLocation().getLocationContext();
10743bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks    if (RootLC->getCurrentStackFrame() != CalleeSF) {
1075e62f048960645b79363408fdead53fec2a063c52Anna Zaks      Engine.FunctionSummaries->markReachedMaxBlockCount(CalleeSF->getDecl());
10763bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks
10775903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      // Re-run the call evaluation without inlining it, by storing the
10785903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      // no-inlining policy in the state and enqueuing the new work item on
10795903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      // the list. Replay should almost never fail. Use the stats to catch it
10805903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      // if it does.
1081255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek      if ((!AMgr.options.NoRetryExhausted &&
1082255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek           replayWithoutInlining(pred, CalleeLC)))
1083253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks        return;
1084253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks      NumMaxBlockCountReachedInInlined++;
10855903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    } else
1086749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks      NumMaxBlockCountReached++;
1087253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks
1088253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks    // Make sink nodes as exhausted(for stats) only if retry failed.
1089253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks    Engine.blocksExhausted.push_back(std::make_pair(L, Sink));
109027c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek  }
1091e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek}
1092e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek
1093e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===//
1094e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek// Branch processing.
1095e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===//
1096e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek
10976ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// RecoverCastedSymbol - A helper function for ProcessBranch that is used
10986ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// to try to recover some path-sensitivity for casts of symbolic
10996ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// integers that promote their values (which are currently not tracked well).
11006ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// This function returns the SVal bound to Condition->IgnoreCasts if all the
11016ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek//  cast(s) did was sign-extend the original value.
1102294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekstatic SVal RecoverCastedSymbol(ProgramStateManager& StateMgr,
11038bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek                                ProgramStateRef state,
1104294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek                                const Stmt *Condition,
11055eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                const LocationContext *LCtx,
1106294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek                                ASTContext &Ctx) {
11076ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek
110803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const Expr *Ex = dyn_cast<Expr>(Condition);
11096ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek  if (!Ex)
11106ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek    return UnknownVal();
11116ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek
11126ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek  uint64_t bits = 0;
11136ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek  bool bitsInit = false;
11141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
111503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  while (const CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
11166ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek    QualType T = CE->getType();
11176ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek
11186ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek    if (!T->isIntegerType())
11196ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek      return UnknownVal();
11201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11216ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek    uint64_t newBits = Ctx.getTypeSize(T);
11226ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek    if (!bitsInit || newBits < bits) {
11236ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek      bitsInit = true;
11246ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek      bits = newBits;
11256ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek    }
11261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11276ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek    Ex = CE->getSubExpr();
11286ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek  }
11296ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek
11306ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek  // We reached a non-cast.  Is it a symbolic value?
11316ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek  QualType T = Ex->getType();
11326ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek
11336ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek  if (!bitsInit || !T->isIntegerType() || Ctx.getTypeSize(T) > bits)
11346ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek    return UnknownVal();
11351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11365eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  return state->getSVal(Ex, LCtx);
11376ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek}
11386ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek
11393f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenekstatic const Stmt *ResolveCondition(const Stmt *Condition,
11403f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek                                    const CFGBlock *B) {
11413f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  if (const Expr *Ex = dyn_cast<Expr>(Condition))
11423f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    Condition = Ex->IgnoreParens();
11433f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek
11443f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  const BinaryOperator *BO = dyn_cast<BinaryOperator>(Condition);
11453f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  if (!BO || !BO->isLogicalOp())
11463f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    return Condition;
11473f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek
11483f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  // For logical operations, we still have the case where some branches
11493f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  // use the traditional "merge" approach and others sink the branch
11503f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  // directly into the basic blocks representing the logical operation.
11513f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  // We need to distinguish between those two cases here.
11523f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek
11533f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  // The invariants are still shifting, but it is possible that the
11543f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  // last element in a CFGBlock is not a CFGStmt.  Look for the last
11553f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  // CFGStmt as the value of the condition.
11563f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  CFGBlock::const_reverse_iterator I = B->rbegin(), E = B->rend();
11573f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  for (; I != E; ++I) {
11583f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    CFGElement Elem = *I;
11593f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    CFGStmt *CS = dyn_cast<CFGStmt>(&Elem);
11603f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    if (!CS)
11613f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek      continue;
11623f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    if (CS->getStmt() != Condition)
11633f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek      break;
11643f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    return Condition;
11653f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  }
11663f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek
11673f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  assert(I != E);
11683f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek
11693f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  while (Condition) {
11703f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    BO = dyn_cast<BinaryOperator>(Condition);
11713f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    if (!BO || !BO->isLogicalOp())
11723f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek      return Condition;
11733f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    Condition = BO->getRHS()->IgnoreParens();
11743f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  }
11753f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  llvm_unreachable("could not resolve condition");
11763f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek}
11773f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek
11789c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
1179a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks                               NodeBuilderContext& BldCtx,
1180ad62deeb70e97da6bd514dd390ea1ce6af6ad81dAnna Zaks                               ExplodedNode *Pred,
11811aae01a8308d2f8e31adab3f4d7ac35543aac680Anna Zaks                               ExplodedNodeSet &Dst,
1182a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks                               const CFGBlock *DstT,
1183a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks                               const CFGBlock *DstF) {
118466c486f275531df6362b3511fc3af6563561801bTed Kremenek  currBldrCtx = &BldCtx;
1185f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks
1186b2331834a0515c80862ee51325c758a053829f15Ted Kremenek  // Check for NULL conditions; e.g. "for(;;)"
11871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (!Condition) {
11881aae01a8308d2f8e31adab3f4d7ac35543aac680Anna Zaks    BranchNodeBuilder NullCondBldr(Pred, Dst, BldCtx, DstT, DstF);
1189a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks    NullCondBldr.markInfeasible(false);
11904e82d3cf6fd4c907265e3fa3aac0a835c35dc759Anna Zaks    NullCondBldr.generateNode(Pred->getState(), true, Pred);
1191b2331834a0515c80862ee51325c758a053829f15Ted Kremenek    return;
1192b2331834a0515c80862ee51325c758a053829f15Ted Kremenek  }
11931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11943f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek
11953f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  // Resolve the condition in the precense of nested '||' and '&&'.
11963f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  if (const Expr *Ex = dyn_cast<Expr>(Condition))
11973f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    Condition = Ex->IgnoreParens();
11983f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek
11993f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  Condition = ResolveCondition(Condition, BldCtx.getBlock());
120021028dd8850c64a414f7a82dfddcc291351203d6Ted Kremenek  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
120121028dd8850c64a414f7a82dfddcc291351203d6Ted Kremenek                                Condition->getLocStart(),
120221028dd8850c64a414f7a82dfddcc291351203d6Ted Kremenek                                "Error evaluating branch");
12030fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek
1204f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks  ExplodedNodeSet CheckersOutSet;
1205f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks  getCheckerManager().runCheckersForBranchCondition(Condition, CheckersOutSet,
12064e82d3cf6fd4c907265e3fa3aac0a835c35dc759Anna Zaks                                                    Pred, *this);
12078ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks  // We generated only sinks.
1208f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks  if (CheckersOutSet.empty())
12098ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks    return;
12101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1211f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks  BranchNodeBuilder builder(CheckersOutSet, Dst, BldCtx, DstT, DstF);
1212f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks  for (NodeBuilder::iterator I = CheckersOutSet.begin(),
1213f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks                             E = CheckersOutSet.end(); E != I; ++I) {
1214cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    ExplodedNode *PredI = *I;
1215cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks
1216cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    if (PredI->isSink())
1217cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks      continue;
1218cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks
12198bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek    ProgramStateRef PrevState = Pred->getState();
12205eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    SVal X = PrevState->getSVal(Condition, Pred->getLocationContext());
1221cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks
1222cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    if (X.isUnknownOrUndef()) {
1223cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks      // Give it a chance to recover from unknown.
1224cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks      if (const Expr *Ex = dyn_cast<Expr>(Condition)) {
1225cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks        if (Ex->getType()->isIntegerType()) {
1226cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks          // Try to recover some path-sensitivity.  Right now casts of symbolic
1227cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks          // integers that promote their values are currently not tracked well.
1228cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks          // If 'Condition' is such an expression, try and recover the
1229cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks          // underlying value and use that instead.
1230cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks          SVal recovered = RecoverCastedSymbol(getStateManager(),
1231cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks                                               PrevState, Condition,
12325eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                               Pred->getLocationContext(),
1233cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks                                               getContext());
1234cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks
1235cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks          if (!recovered.isUnknown()) {
1236cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks            X = recovered;
1237cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks          }
12380835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu        }
1239b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek      }
12400835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu    }
12415eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek
12420835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu    // If the condition is still unknown, give up.
124373c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis    if (X.isUnknownOrUndef()) {
1244829846b5002d7f8d6a54b9c58c3ecf7cac56d2ccTed Kremenek      builder.generateNode(PrevState, true, PredI);
1245829846b5002d7f8d6a54b9c58c3ecf7cac56d2ccTed Kremenek      builder.generateNode(PrevState, false, PredI);
1246cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks      continue;
12471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
12481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1249cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    DefinedSVal V = cast<DefinedSVal>(X);
12500835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu
1251cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    // Process the true branch.
1252cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    if (builder.isFeasible(true)) {
12538bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek      if (ProgramStateRef state = PrevState->assume(V, true))
1254829846b5002d7f8d6a54b9c58c3ecf7cac56d2ccTed Kremenek        builder.generateNode(state, true, PredI);
1255cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks      else
1256cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks        builder.markInfeasible(true);
1257cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    }
12581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1259cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    // Process the false branch.
1260cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    if (builder.isFeasible(false)) {
12618bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek      if (ProgramStateRef state = PrevState->assume(V, false))
1262829846b5002d7f8d6a54b9c58c3ecf7cac56d2ccTed Kremenek        builder.generateNode(state, false, PredI);
1263cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks      else
1264cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks        builder.markInfeasible(false);
1265cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    }
1266cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks  }
126766c486f275531df6362b3511fc3af6563561801bTed Kremenek  currBldrCtx = 0;
1268f233d48cfc513b045e2c2cfca5c175220fbd0a82Ted Kremenek}
1269f233d48cfc513b045e2c2cfca5c175220fbd0a82Ted Kremenek
1270e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek/// processIndirectGoto - Called by CoreEngine.  Used to generate successor
1271754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek///  nodes by processing the 'effects' of a computed goto jump.
1272ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattnervoid ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) {
1273754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek
12748bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef state = builder.getState();
12755eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  SVal V = state->getSVal(builder.getTarget(), builder.getLocationContext());
12761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1277754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  // Three possibilities:
1278754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  //
1279754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  //   (1) We know the computed label.
12804a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek  //   (2) The label is NULL (or some other constant), or Undefined.
1281754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  //   (3) We have no clue about the label.  Dispatch to all targets.
1282754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  //
12831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1284d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  typedef IndirectGotoNodeBuilder::iterator iterator;
1285754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek
12861c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  if (isa<loc::GotoLabel>(V)) {
1287ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner    const LabelDecl *L = cast<loc::GotoLabel>(V).getLabel();
12881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1289ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner    for (iterator I = builder.begin(), E = builder.end(); I != E; ++I) {
129024f1a967741ff9f8025ee23be12ba6feacc31f77Ted Kremenek      if (I.getLabel() == L) {
1291a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek        builder.generateNode(I, state);
1292754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek        return;
1293754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek      }
1294754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek    }
12951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1296b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie    llvm_unreachable("No block with label.");
1297754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  }
1298754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek
12991c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  if (isa<loc::ConcreteInt>(V) || isa<UndefinedVal>(V)) {
1300754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek    // Dispatch to the first target and mark it as a sink.
13012055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu    //ExplodedNode* N = builder.generateNode(builder.begin(), state, true);
13022055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu    // FIXME: add checker visit.
13032055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu    //    UndefBranches.insert(N);
1304754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek    return;
1305754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  }
13061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1307754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  // This is really a catch-all.  We don't support symbolics yet.
1308b3cfd58c9b13325d994e5f9b5065e6a22d91911dTed Kremenek  // FIXME: Implement dispatch for symbolic pointers.
13091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1310754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  for (iterator I=builder.begin(), E=builder.end(); I != E; ++I)
1311a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek    builder.generateNode(I, state);
1312754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek}
1313f233d48cfc513b045e2c2cfca5c175220fbd0a82Ted Kremenek
1314d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis/// ProcessEndPath - Called by CoreEngine.  Used to generate end-of-path
131573099bfea9f5d4ec05265170bbefec3d76fb6b5eTed Kremenek///  nodes when the control reaches the end of a function.
1316af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaksvoid ExprEngine::processEndOfFunction(NodeBuilderContext& BC) {
1317af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks  StateMgr.EndPath(BC.Pred->getState());
1318af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks  ExplodedNodeSet Dst;
1319af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks  getCheckerManager().runCheckersForEndPath(BC, Dst, *this);
13204d2ae4a70336dc2aa11389b34946be152bb454c9Anna Zaks  Engine.enqueueEndOfFunction(Dst);
132173099bfea9f5d4ec05265170bbefec3d76fb6b5eTed Kremenek}
132273099bfea9f5d4ec05265170bbefec3d76fb6b5eTed Kremenek
1323d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis/// ProcessSwitch - Called by CoreEngine.  Used to generate successor
1324daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek///  nodes by processing the 'effects' of a switch statement.
1325e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenekvoid ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
1326d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  typedef SwitchNodeBuilder::iterator iterator;
13278bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef state = builder.getState();
13289c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const Expr *CondE = builder.getCondition();
13295eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  SVal  CondV_untested = state->getSVal(CondE, builder.getLocationContext());
1330daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek
13315b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  if (CondV_untested.isUndef()) {
13322055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu    //ExplodedNode* N = builder.generateDefaultCaseNode(state, true);
1333b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek    // FIXME: add checker
13342055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu    //UndefBranches.insert(N);
13352055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu
1336daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek    return;
1337daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek  }
13385b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  DefinedOrUnknownSVal CondV = cast<DefinedOrUnknownSVal>(CondV_untested);
1339692416c214a3b234236dedcf875735a9cc29e90bTed Kremenek
13408bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef DefaultSt = state;
134134feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek
134234feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek  iterator I = builder.begin(), EI = builder.end();
134334feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek  bool defaultIsFeasible = I == EI;
13441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
134534feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek  for ( ; I != EI; ++I) {
1346e71f3d587844110d836c82250830b27b1651afdbTed Kremenek    // Successor may be pruned out during CFG construction.
1347e71f3d587844110d836c82250830b27b1651afdbTed Kremenek    if (!I.getBlock())
1348e71f3d587844110d836c82250830b27b1651afdbTed Kremenek      continue;
1349e71f3d587844110d836c82250830b27b1651afdbTed Kremenek
13509c378f705405d37f49795d5e915989de774fe11fTed Kremenek    const CaseStmt *Case = I.getCase();
135172afb3739da0da02158242ae41a50cfe0bea78b4Ted Kremenek
135272afb3739da0da02158242ae41a50cfe0bea78b4Ted Kremenek    // Evaluate the LHS of the case value.
135385df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith    llvm::APSInt V1 = Case->getLHS()->EvaluateKnownConstInt(getContext());
135485df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith    assert(V1.getBitWidth() == getContext().getTypeSize(CondE->getType()));
13551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1356daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek    // Get the RHS of the case, if it exists.
135785df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith    llvm::APSInt V2;
135885df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith    if (const Expr *E = Case->getRHS())
135985df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith      V2 = E->EvaluateKnownConstInt(getContext());
136014a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek    else
136114a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek      V2 = V1;
13621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1363daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek    // FIXME: Eventually we should replace the logic below with a range
1364daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek    //  comparison, rather than concretize the values within the range.
1365aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    //  This should be easy once we have "ranges" for NonLVals.
13661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
136714a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek    do {
136885df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith      nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1));
13699c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek      DefinedOrUnknownSVal Res = svalBuilder.evalEQ(DefaultSt ? DefaultSt : state,
137048569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek                                               CondV, CaseVal);
1371b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
13721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      // Now "assume" that the case matches.
13738bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek      if (ProgramStateRef stateNew = state->assume(Res, true)) {
1374a591bc04d21fa62ebffcb2c7814d738ca8f5e2f9Ted Kremenek        builder.generateCaseStmtNode(I, stateNew);
13751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1376daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek        // If CondV evaluates to a constant, then we know that this
1377daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek        // is the *only* case that we can take, so stop evaluating the
1378daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek        // others.
13791c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu        if (isa<nonloc::ConcreteInt>(CondV))
1380daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek          return;
1381daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek      }
13821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1383daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek      // Now "assume" that the case doesn't match.  Add this state
1384daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek      // to the default state (if it is feasible).
138548569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek      if (DefaultSt) {
13868bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek        if (ProgramStateRef stateNew = DefaultSt->assume(Res, false)) {
138748569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek          defaultIsFeasible = true;
138848569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek          DefaultSt = stateNew;
138948569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek        }
139048569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek        else {
139148569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek          defaultIsFeasible = false;
139248569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek          DefaultSt = NULL;
139348569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek        }
13945014ab113eb211b8320ae30b173d7020352663c6Ted Kremenek      }
1395b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
139614a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek      // Concretize the next value in the range.
139785df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith      if (V1 == V2)
139814a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek        break;
13991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
140085df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith      ++V1;
140185df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith      assert (V1 <= V2);
14021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
140314a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek    } while (true);
1404daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek  }
14051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14064d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  if (!defaultIsFeasible)
14074d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek    return;
14084d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek
14094d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  // If we have switch(enum value), the default branch is not
14104d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  // feasible if all of the enum constants not covered by 'case:' statements
14114d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  // are not feasible values for the switch condition.
14124d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  //
14134d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  // Note that this isn't as accurate as it could be.  Even if there isn't
14144d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  // a case for a particular enum value as long as that enum value isn't
14154d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  // feasible then it shouldn't be considered for making 'default:' reachable.
14164d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  const SwitchStmt *SS = builder.getSwitch();
14174d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  const Expr *CondExpr = SS->getCond()->IgnoreParenImpCasts();
14184d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  if (CondExpr->getType()->getAs<EnumType>()) {
14194d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek    if (SS->isAllEnumCasesCovered())
14204d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek      return;
14214d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  }
14224d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek
14234d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  builder.generateDefaultCaseNode(DefaultSt);
1424daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek}
1425daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek
1426e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===//
1427ec96a2d52d16e150baaf629cd35e3fabff5d8915Ted Kremenek// Transfer functions: Loads and stores.
1428e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===//
1429d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek
1430d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D,
1431d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis                                        ExplodedNode *Pred,
1432d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis                                        ExplodedNodeSet &Dst) {
143366c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
1434ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks
14358bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef state = Pred->getState();
14365eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  const LocationContext *LCtx = Pred->getLocationContext();
14376d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu
14389c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1439591b5f53c0e11d87401b4804bb1be1a53f95c619Anna Zaks    assert(Ex->isGLValue());
1440d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek    SVal V = state->getLValue(VD, Pred->getLocationContext());
1441a7581731b1453b51b26154d2409d42a5b6395079Zhongxing Xu
1442892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    // For references, the 'lvalue' is the pointer address stored in the
1443892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    // reference region.
1444892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    if (VD->getType()->isReferenceType()) {
1445892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      if (const MemRegion *R = V.getAsRegion())
1446892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek        V = state->getSVal(R);
1447892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      else
1448892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek        V = UnknownVal();
1449852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek    }
14506d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu
1451fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0,
1452ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks                      ProgramPoint::PostLValueKind);
1453852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek    return;
1454892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek  }
14559c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (const EnumConstantDecl *ED = dyn_cast<EnumConstantDecl>(D)) {
1456591b5f53c0e11d87401b4804bb1be1a53f95c619Anna Zaks    assert(!Ex->isGLValue());
1457c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    SVal V = svalBuilder.makeIntVal(ED->getInitVal());
14585eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V));
14596d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu    return;
1460892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek  }
14619c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1462c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    SVal V = svalBuilder.getFunctionPointer(FD);
1463fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0,
1464ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks                      ProgramPoint::PostLValueKind);
14656d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu    return;
14661b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  }
14675aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek  if (isa<FieldDecl>(D)) {
1468fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    // FIXME: Compute lvalue of field pointers-to-member.
14690156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose    // Right now we just use a non-null void pointer, so that it gives proper
14700156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose    // results in boolean contexts.
14710156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose    SVal V = svalBuilder.conjureSymbolVal(Ex, LCtx, getContext().VoidPtrTy,
14720156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose                                          currBldrCtx->blockCount());
14730156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose    state = state->assume(cast<DefinedOrUnknownSVal>(V), true);
14740156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0,
1475fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose		      ProgramPoint::PostLValueKind);
14765aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek    return;
14775aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek  }
14785aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek
1479fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose  llvm_unreachable("Support for this Decl not implemented.");
14803271f8d315712885ac87747369bb1d9f4b1ea81fTed Kremenek}
14813271f8d315712885ac87747369bb1d9f4b1ea81fTed Kremenek
1482540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek/// VisitArraySubscriptExpr - Transfer function for array accesses
14839c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *A,
14849c378f705405d37f49795d5e915989de774fe11fTed Kremenek                                             ExplodedNode *Pred,
14859c378f705405d37f49795d5e915989de774fe11fTed Kremenek                                             ExplodedNodeSet &Dst){
14861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14879c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const Expr *Base = A->getBase()->IgnoreParens();
14889c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const Expr *Idx  = A->getIdx()->IgnoreParens();
1489892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek
14901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14918f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek  ExplodedNodeSet checkerPreStmt;
14928f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek  getCheckerManager().runCheckersForPreStmt(checkerPreStmt, Pred, A, *this);
14938f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek
149466c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(checkerPreStmt, Dst, *currBldrCtx);
1495ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks
14968f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek  for (ExplodedNodeSet::iterator it = checkerPreStmt.begin(),
14978f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek                                 ei = checkerPreStmt.end(); it != ei; ++it) {
14985eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    const LocationContext *LCtx = (*it)->getLocationContext();
14998bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek    ProgramStateRef state = (*it)->getState();
15005eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    SVal V = state->getLValue(A->getType(),
15015eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                              state->getSVal(Idx, LCtx),
15025eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                              state->getSVal(Base, LCtx));
1503591b5f53c0e11d87401b4804bb1be1a53f95c619Anna Zaks    assert(A->isGLValue());
1504fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    Bldr.generateNode(A, *it, state->BindExpr(A, LCtx, V), 0,
1505fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose                      ProgramPoint::PostLValueKind);
15061b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  }
1507540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek}
1508540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek
1509469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek/// VisitMemberExpr - Transfer function for member expressions.
15109c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
15116889679d72859960e0fc8d1080487f63c4df1e0aAnna Zaks                                 ExplodedNodeSet &TopDst) {
15121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
151366c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(Pred, TopDst, *currBldrCtx);
15146889679d72859960e0fc8d1080487f63c4df1e0aAnna Zaks  ExplodedNodeSet Dst;
1515603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose  ValueDecl *Member = M->getMemberDecl();
151610f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek
1517603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose  // Handle static member variables and enum constants accessed via
1518603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose  // member syntax.
1519603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose  if (isa<VarDecl>(Member) || isa<EnumConstantDecl>(Member)) {
1520ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks    Bldr.takeNodes(Pred);
1521603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose    VisitCommonDeclRefExpr(M, Member, Pred, Dst);
1522ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks    Bldr.addNodes(Dst);
15235bd04952d4ae7ca894f583583208f0cec4735a90Ted Kremenek    return;
15245bd04952d4ae7ca894f583583208f0cec4735a90Ted Kremenek  }
152510f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek
1526f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  ProgramStateRef state = Pred->getState();
1527f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  const LocationContext *LCtx = Pred->getLocationContext();
1528f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  Expr *BaseExpr = M->getBase();
1529f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
153010f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek  // Handle C++ method calls.
1531603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) {
1532f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose    if (MD->isInstance())
1533f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose      state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
153410f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek
1535f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose    SVal MDVal = svalBuilder.getFunctionPointer(MD);
1536f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose    state = state->BindExpr(M, LCtx, MDVal);
153720aa40342bd74895128860c081aa84cd85bfa68dJordan Rose
1538f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose    Bldr.generateNode(M, Pred, state);
1539ce6644bc1e921833f9b3c10cf7d4a0b78e8d5dc9Jordan Rose    return;
154020aa40342bd74895128860c081aa84cd85bfa68dJordan Rose  }
154120aa40342bd74895128860c081aa84cd85bfa68dJordan Rose
1542f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  // Handle regular struct fields / member variables.
1543f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
1544f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  SVal baseExprVal = state->getSVal(BaseExpr, LCtx);
1545d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose
1546603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose  FieldDecl *field = cast<FieldDecl>(Member);
1547e3939d7446959afb6b650fe08e952d0f64ab6794Ted Kremenek  SVal L = state->getLValue(field, baseExprVal);
15486b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose  if (M->isGLValue()) {
15496b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose    if (field->getType()->isReferenceType()) {
1550d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose      if (const MemRegion *R = L.getAsRegion())
1551d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose        L = state->getSVal(R);
1552d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose      else
15536b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose        L = UnknownVal();
15546b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose    }
15556b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose
1556d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose    Bldr.generateNode(M, Pred, state->BindExpr(M, LCtx, L), 0,
1557d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose                      ProgramPoint::PostLValueKind);
15586b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose  } else {
1559ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks    Bldr.takeNodes(Pred);
1560bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek    evalLoad(Dst, M, M, Pred, state, L);
1561ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks    Bldr.addNodes(Dst);
1562ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks  }
1563469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek}
1564469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek
15659c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek/// evalBind - Handle the semantics of binding a value to a specific location.
15669c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek///  This method is used by evalStore and (soon) VisitDeclStmt, and others.
15679c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
156893bd5ca766c4d7906878f4ffe76ce1b2080e540bJordy Rose                          ExplodedNode *Pred,
156932a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek                          SVal location, SVal Val,
15703682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose                          bool atDeclInit, const ProgramPoint *PP) {
15713682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose
15723682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  const LocationContext *LC = Pred->getLocationContext();
15733682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  PostStmt PS(StoreE, LC);
15743682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  if (!PP)
15753682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose    PP = &PS;
1576b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
1577b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek  // Do a previsit of the bind.
1578fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose  ExplodedNodeSet CheckedSet;
1579fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose  getCheckerManager().runCheckersForBind(CheckedSet, Pred, location, Val,
15803682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose                                         StoreE, *this, *PP);
1581b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
158232a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek  // If the location is not a 'Loc', it will already be handled by
158332a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek  // the checkers.  There is nothing left to do.
158432a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek  if (!isa<Loc>(location)) {
158532a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek    Dst = CheckedSet;
158632a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek    return;
158732a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek  }
158832a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek
15896b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks  ExplodedNodeSet TmpDst;
159066c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(CheckedSet, TmpDst, *currBldrCtx);
15916b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks
1592b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek  for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
1593b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek       I!=E; ++I) {
15943d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    ExplodedNode *PredI = *I;
15953d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    ProgramStateRef state = PredI->getState();
159632a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek
159732a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek    // When binding the value, pass on the hint that this is a initialization.
159832a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek    // For initializations, we do not need to inform clients of region
159932a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek    // changes.
160032a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek    state = state->bindLoc(cast<Loc>(location),
160132a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek                           Val, /* notifyChanges = */ !atDeclInit);
160232a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek
16033d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    const MemRegion *LocReg = 0;
160432a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek    if (loc::MemRegionVal *LocRegVal = dyn_cast<loc::MemRegionVal>(&location)) {
16053d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks      LocReg = LocRegVal->getRegion();
160632a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek    }
16073682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose
16083d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    const ProgramPoint L = PostStore(StoreE, LC, LocReg, 0);
1609fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    Bldr.generateNode(L, state, PredI);
1610b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek  }
16116b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks  Dst.insert(TmpDst);
1612a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek}
1613a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek
16149c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek/// evalStore - Handle the semantics of a store via an assignment.
1615a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek///  @param Dst The node set to store generated state nodes
16162e6f5b823912ae76211427cb8684c9eaa6e53a1fJames Dennett///  @param AssignE The assignment expression if the store happens in an
1617e8a4d7d0064b357a30fe7ee4f2ddc02f9ffc0357Zhongxing Xu///         assignment.
16182e6f5b823912ae76211427cb8684c9eaa6e53a1fJames Dennett///  @param LocationE The location expression that is stored to.
1619a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek///  @param state The current simulation state
1620a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek///  @param location The location to store the value
1621a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek///  @param Val The value to be stored
16229c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE,
16239c378f705405d37f49795d5e915989de774fe11fTed Kremenek                             const Expr *LocationE,
16249c378f705405d37f49795d5e915989de774fe11fTed Kremenek                             ExplodedNode *Pred,
16258bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek                             ProgramStateRef state, SVal location, SVal Val,
1626ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek                             const ProgramPointTag *tag) {
162714429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis  // Proceed with the store.  We use AssignE as the anchor for the PostStore
162814429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis  // ProgramPoint if it is non-NULL, and LocationE otherwise.
162914429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis  const Expr *StoreE = AssignE ? AssignE : LocationE;
163014429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis
16311b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  // Evaluate the location (checks for bad dereferences).
1632b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  ExplodedNodeSet Tmp;
1633bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek  evalLocation(Tmp, AssignE, LocationE, Pred, state, location, tag, false);
16341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1635b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  if (Tmp.empty())
16361b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    return;
1637b0533965f1b4db020692e3b23ca7b3bc15bf5897Ted Kremenek
163873c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis  if (location.isUndef())
163973c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis    return;
1640a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek
1641b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI)
16423d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    evalBind(Dst, StoreE, *NI, location, Val, false);
16431b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek}
16441b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
1645bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenekvoid ExprEngine::evalLoad(ExplodedNodeSet &Dst,
1646bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                          const Expr *NodeEx,
1647bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                          const Expr *BoundEx,
1648bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                          ExplodedNode *Pred,
1649bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                          ProgramStateRef state,
1650bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                          SVal location,
1651bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                          const ProgramPointTag *tag,
1652bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                          QualType LoadTy)
1653bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek{
1654cca8ab155e8c20b98ba2d90eb2b1c228895e06fdZhanyong Wan  assert(!isa<NonLoc>(location) && "location cannot be a NonLoc.");
165514429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis
16565b8c69494881b7d35bc6244b4a19be0cc2eab368Jordan Rose  // Are we loading from a region?  This actually results in two loads; one
1657852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  // to fetch the address of the referenced value and one to fetch the
1658852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  // referenced value.
16599697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek  if (const TypedValueRegion *TR =
16609697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek        dyn_cast_or_null<TypedValueRegion>(location.getAsRegion())) {
1661b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
1662018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu    QualType ValTy = TR->getValueType();
1663852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek    if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) {
1664ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek      static SimpleProgramPointTag
1665ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek             loadReferenceTag("ExprEngine : Load Reference");
1666852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek      ExplodedNodeSet Tmp;
1667bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek      evalLoadCommon(Tmp, NodeEx, BoundEx, Pred, state,
1668bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                     location, &loadReferenceTag,
1669852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek                     getContext().getPointerType(RT->getPointeeType()));
1670852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek
1671852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek      // Perform the load from the referenced value.
1672852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end() ; I!=E; ++I) {
1673db5e8cd095d1ffdd18f5620ad2348b5f386bebe3Anna Zaks        state = (*I)->getState();
1674bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek        location = state->getSVal(BoundEx, (*I)->getLocationContext());
1675bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek        evalLoadCommon(Dst, NodeEx, BoundEx, *I, state, location, tag, LoadTy);
1676b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek      }
1677852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek      return;
1678852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek    }
1679852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  }
1680b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
1681bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek  evalLoadCommon(Dst, NodeEx, BoundEx, Pred, state, location, tag, LoadTy);
1682852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek}
1683852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek
1684bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenekvoid ExprEngine::evalLoadCommon(ExplodedNodeSet &Dst,
1685bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                                const Expr *NodeEx,
1686bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                                const Expr *BoundEx,
1687bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                                ExplodedNode *Pred,
1688bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                                ProgramStateRef state,
1689bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                                SVal location,
1690bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                                const ProgramPointTag *tag,
1691bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                                QualType LoadTy) {
1692bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek  assert(NodeEx);
1693bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek  assert(BoundEx);
16941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Evaluate the location (checks for bad dereferences).
1695b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  ExplodedNodeSet Tmp;
1696bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek  evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location, tag, true);
1697b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  if (Tmp.empty())
16981b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    return;
1699b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
170066c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(Tmp, Dst, *currBldrCtx);
170173c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis  if (location.isUndef())
170273c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis    return;
1703b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
17041b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  // Proceed with the load.
1705b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) {
1706db5e8cd095d1ffdd18f5620ad2348b5f386bebe3Anna Zaks    state = (*NI)->getState();
17075eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    const LocationContext *LCtx = (*NI)->getLocationContext();
170896ebad66c451d79c9f57b1edb31efaeeb23b9a01Ted Kremenek
1709b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    if (location.isUnknown()) {
1710b4b817d704287836b52b34369009e682f208aa2bTed Kremenek      // This is important.  We must nuke the old binding.
1711bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek      Bldr.generateNode(NodeEx, *NI,
1712bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                        state->BindExpr(BoundEx, LCtx, UnknownVal()),
1713fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose                        tag, ProgramPoint::PostLoadKind);
1714b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    }
1715b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    else {
171696ebad66c451d79c9f57b1edb31efaeeb23b9a01Ted Kremenek      if (LoadTy.isNull())
1717bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek        LoadTy = BoundEx->getType();
171896ebad66c451d79c9f57b1edb31efaeeb23b9a01Ted Kremenek      SVal V = state->getSVal(cast<Loc>(location), LoadTy);
1719bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek      Bldr.generateNode(NodeEx, *NI,
1720bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                        state->bindExprAndLocation(BoundEx, LCtx, location, V),
1721fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose                        tag, ProgramPoint::PostLoadKind);
1722b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    }
1723d5b499d43c3526fae7f9ebb6e2d50e79d3496cedZhongxing Xu  }
17241b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek}
17251b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
1726bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenekvoid ExprEngine::evalLocation(ExplodedNodeSet &Dst,
1727bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              const Stmt *NodeEx,
1728bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              const Stmt *BoundEx,
1729bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              ExplodedNode *Pred,
1730bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              ProgramStateRef state,
1731bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              SVal location,
1732bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              const ProgramPointTag *tag,
1733bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              bool isLoad) {
173466c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder BldrTop(Pred, Dst, *currBldrCtx);
173500b1ad2d56f3e39f95c3f61bf511a531ab6a4fa5Zhongxing Xu  // Early checks for performance reason.
1736769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  if (location.isUnknown()) {
1737b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    return;
1738b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  }
1739b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
17409c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis  ExplodedNodeSet Src;
1741ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks  BldrTop.takeNodes(Pred);
174266c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(Pred, Src, *currBldrCtx);
1743ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks  if (Pred->getState() != state) {
1744eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis    // Associate this new state with an ExplodedNode.
1745eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis    // FIXME: If I pass null tag, the graph is incorrect, e.g for
1746eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis    //   int *p;
1747eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis    //   p = 0;
1748eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis    //   *p = 0xDEADBEEF;
1749eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis    // "p = 0" is not noted as "Null pointer value stored to 'p'" but
1750eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis    // instead "int *p" is noted as
1751eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis    // "Variable 'p' initialized to a null pointer value"
1752ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek
1753fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    static SimpleProgramPointTag tag("ExprEngine: Location");
1754fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    Bldr.generateNode(NodeEx, Pred, state, &tag);
17550296c22557b3735e2ffeff690eb46fb0e9152bccTed Kremenek  }
1756ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks  ExplodedNodeSet Tmp;
1757bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek  getCheckerManager().runCheckersForLocation(Tmp, Src, location, isLoad,
1758bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                                             NodeEx, BoundEx, *this);
1759ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks  BldrTop.addNodes(Tmp);
1760ec96a2d52d16e150baaf629cd35e3fabff5d8915Ted Kremenek}
1761ec96a2d52d16e150baaf629cd35e3fabff5d8915Ted Kremenek
17626c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenekstd::pair<const ProgramPointTag *, const ProgramPointTag*>
17630caa2d47b84337e942b3f6652adfafe4ae506cfeTed KremenekExprEngine::geteagerlyAssumeBinOpBifurcationTags() {
17646c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek  static SimpleProgramPointTag
17650caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek         eagerlyAssumeBinOpBifurcationTrue("ExprEngine : Eagerly Assume True"),
17660caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek         eagerlyAssumeBinOpBifurcationFalse("ExprEngine : Eagerly Assume False");
17670caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek  return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue,
17680caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek                        &eagerlyAssumeBinOpBifurcationFalse);
17696c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek}
17706c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek
17710caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenekvoid ExprEngine::evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst,
17720caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek                                                   ExplodedNodeSet &Src,
17730caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek                                                   const Expr *Ex) {
177466c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(Src, Dst, *currBldrCtx);
177586b39f20d5091ca3fdcbeb4a22766aaffdf6ac35Ted Kremenek
1776031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) {
1777031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu    ExplodedNode *Pred = *I;
1778b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek    // Test if the previous node was as the same expression.  This can happen
1779b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek    // when the expression fails to evaluate to anything meaningful and
1780b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek    // (as an optimization) we don't generate a node.
17811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ProgramPoint P = Pred->getLocation();
1782b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek    if (!isa<PostStmt>(P) || cast<PostStmt>(P).getStmt() != Ex) {
1783b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek      continue;
17841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
1785b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek
17868bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek    ProgramStateRef state = Pred->getState();
17875eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    SVal V = state->getSVal(Ex, Pred->getLocationContext());
17885344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks    nonloc::SymbolVal *SEV = dyn_cast<nonloc::SymbolVal>(&V);
17895344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks    if (SEV && SEV->isExpression()) {
17906c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek      const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags =
17910caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek        geteagerlyAssumeBinOpBifurcationTags();
17926c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek
179348af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek      // First assume that the condition is true.
17948bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek      if (ProgramStateRef StateTrue = state->assume(*SEV, true)) {
179586b39f20d5091ca3fdcbeb4a22766aaffdf6ac35Ted Kremenek        SVal Val = svalBuilder.makeIntVal(1U, Ex->getType());
17965eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek        StateTrue = StateTrue->BindExpr(Ex, Pred->getLocationContext(), Val);
1797fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose        Bldr.generateNode(Ex, Pred, StateTrue, tags.first);
179848af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek      }
17991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
180048af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek      // Next, assume that the condition is false.
18018bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek      if (ProgramStateRef StateFalse = state->assume(*SEV, false)) {
180286b39f20d5091ca3fdcbeb4a22766aaffdf6ac35Ted Kremenek        SVal Val = svalBuilder.makeIntVal(0U, Ex->getType());
18035eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek        StateFalse = StateFalse->BindExpr(Ex, Pred->getLocationContext(), Val);
1804fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose        Bldr.generateNode(Ex, Pred, StateFalse, tags.second);
180548af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek      }
180648af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek    }
180748af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek  }
180848af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek}
180948af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek
1810df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosiervoid ExprEngine::VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred,
1811df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier                                 ExplodedNodeSet &Dst) {
181266c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
1813a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen  // We have processed both the inputs and the outputs.  All of the outputs
1814a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen  // should evaluate to Locs.  Nuke all of their values.
18151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1816a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen  // FIXME: Some day in the future it would be nice to allow a "plug-in"
1817a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen  // which interprets the inline asm and stores proper results in the
1818a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen  // outputs.
18191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1820a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen  ProgramStateRef state = Pred->getState();
18211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1822df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier  for (GCCAsmStmt::const_outputs_iterator OI = A->begin_outputs(),
1823a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen       OE = A->end_outputs(); OI != OE; ++OI) {
1824a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen    SVal X = state->getSVal(*OI, Pred->getLocationContext());
1825a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen    assert (!isa<NonLoc>(X));  // Should be an Lval, or unknown, undef.
18261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1827a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen    if (isa<Loc>(X))
1828a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen      state = state->bindLoc(cast<Loc>(X), UnknownVal());
1829ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek  }
18301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1831a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen  Bldr.generateNode(A, Pred, state);
1832ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek}
1833ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek
18348cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosiervoid ExprEngine::VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred,
18358cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier                                ExplodedNodeSet &Dst) {
183666c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
18378cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier  Bldr.generateNode(A, Pred, Pred->getState());
18388cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier}
18398cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier
1840094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek//===----------------------------------------------------------------------===//
1841e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek// Visualization.
1842ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek//===----------------------------------------------------------------------===//
1843ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek
1844aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek#ifndef NDEBUG
1845d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisstatic ExprEngine* GraphPrintCheckerState;
1846e97ca065c91ff9ca2a2a42eb443eaa553c40441cTed Kremenekstatic SourceManager* GraphPrintSourceManager;
18473b4f6702860208692f6ef28401e68de4e3ff9af9Ted Kremenek
1848aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremeneknamespace llvm {
1849aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenektemplate<>
185047491f8b7adf9d42a404d44c073e8a5308fa6cfcDouglas Gregorstruct DOTGraphTraits<ExplodedNode*> :
1851aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek  public DefaultDOTGraphTraits {
1852006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser
1853006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser  DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
1854006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser
1855d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  // FIXME: Since we do not cache error nodes in ExprEngine now, this does not
1856ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu  // work.
18579c378f705405d37f49795d5e915989de774fe11fTed Kremenek  static std::string getNodeAttributes(const ExplodedNode *N, void*) {
18581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
185910f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#if 0
186010f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek      // FIXME: Replace with a general scheme to tell if the node is
186110f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek      // an error node.
1862a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek    if (GraphPrintCheckerState->isImplicitNullDeref(N) ||
18639dca062461a6244cf0f733346657fa3eee853f9bTed Kremenek        GraphPrintCheckerState->isExplicitNullDeref(N) ||
18644a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek        GraphPrintCheckerState->isUndefDeref(N) ||
18654a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek        GraphPrintCheckerState->isUndefStore(N) ||
18664a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek        GraphPrintCheckerState->isUndefControlFlow(N) ||
18675e03fcb5420c33207433dd6f800588e256dd9bdbTed Kremenek        GraphPrintCheckerState->isUndefResult(N) ||
18682ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek        GraphPrintCheckerState->isBadCall(N) ||
18692ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek        GraphPrintCheckerState->isUndefArg(N))
1870a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek      return "color=\"red\",style=\"filled\"";
18711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18728cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek    if (GraphPrintCheckerState->isNoReturnCall(N))
18738cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return "color=\"blue\",style=\"filled\"";
18742055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu#endif
1875a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek    return "";
1876a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek  }
18771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
187828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose  static void printLocation(llvm::raw_ostream &Out, SourceLocation SLoc) {
187928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose    if (SLoc.isFileID()) {
188028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose      Out << "\\lline="
188128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        << GraphPrintSourceManager->getExpansionLineNumber(SLoc)
188228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        << " col="
188328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        << GraphPrintSourceManager->getExpansionColumnNumber(SLoc)
188428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        << "\\l";
188528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose    }
188628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose  }
188728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose
18889c378f705405d37f49795d5e915989de774fe11fTed Kremenek  static std::string getNodeLabel(const ExplodedNode *N, void*){
18891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
189053ba0b636194dbeaa65a6f85316c9397a0c5298bTed Kremenek    std::string sbuf;
189153ba0b636194dbeaa65a6f85316c9397a0c5298bTed Kremenek    llvm::raw_string_ostream Out(sbuf);
1892803c9edd06e8f936821525d36b1d8cc131e37d44Ted Kremenek
1893803c9edd06e8f936821525d36b1d8cc131e37d44Ted Kremenek    // Program Location.
1894aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek    ProgramPoint Loc = N->getLocation();
18951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1896aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek    switch (Loc.getKind()) {
18970b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      case ProgramPoint::BlockEntranceKind: {
18981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        Out << "Block Entrance: B"
1899aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek            << cast<BlockEntrance>(Loc).getBlock()->getBlockID();
19000b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        if (const NamedDecl *ND =
19010b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                    dyn_cast<NamedDecl>(Loc.getLocationContext()->getDecl())) {
19020b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks          Out << " (";
19030b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks          ND->printName(Out);
19040b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks          Out << ")";
19050b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        }
1906aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek        break;
19070b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      }
19081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1909aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek      case ProgramPoint::BlockExitKind:
1910aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek        assert (false);
1911aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek        break;
19121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1913102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor      case ProgramPoint::CallEnterKind:
1914102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor        Out << "CallEnter";
1915102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor        break;
1916102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
19170b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      case ProgramPoint::CallExitBeginKind:
19180b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        Out << "CallExitBegin";
19190b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        break;
19200b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks
19210b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      case ProgramPoint::CallExitEndKind:
19220b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        Out << "CallExitEnd";
19230b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        break;
19240b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks
19250b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      case ProgramPoint::PostStmtPurgeDeadSymbolsKind:
19260b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        Out << "PostStmtPurgeDeadSymbols";
19270b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        break;
19280b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks
19290b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      case ProgramPoint::PreStmtPurgeDeadSymbolsKind:
19300b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        Out << "PreStmtPurgeDeadSymbols";
1931102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor        break;
1932102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
19335903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      case ProgramPoint::EpsilonKind:
19345903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks        Out << "Epsilon Point";
19355903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks        break;
19365903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
193728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose      case ProgramPoint::PreImplicitCallKind: {
193828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        ImplicitCallPoint *PC = cast<ImplicitCallPoint>(&Loc);
193928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        Out << "PreCall: ";
194028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose
194128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        // FIXME: Get proper printing options.
194228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        PC->getDecl()->print(Out, LangOptions());
194328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        printLocation(Out, PC->getLocation());
194428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        break;
194528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose      }
194628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose
194728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose      case ProgramPoint::PostImplicitCallKind: {
194828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        ImplicitCallPoint *PC = cast<ImplicitCallPoint>(&Loc);
194928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        Out << "PostCall: ";
195028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose
195128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        // FIXME: Get proper printing options.
195228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        PC->getDecl()->print(Out, LangOptions());
195328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        printLocation(Out, PC->getLocation());
195428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        break;
195528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose      }
195628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose
1957aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek      default: {
19585f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek        if (StmtPoint *L = dyn_cast<StmtPoint>(&Loc)) {
19599c378f705405d37f49795d5e915989de774fe11fTed Kremenek          const Stmt *S = L->getStmt();
19608c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
196131ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky          Out << S->getStmtClassName() << ' ' << (const void*) S << ' ';
1962e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner          LangOptions LO; // FIXME.
1963e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner          S->printPretty(Out, 0, PrintingPolicy(LO));
196428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose          printLocation(Out, S->getLocStart());
19651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19665f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek          if (isa<PreStmt>(Loc))
19671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            Out << "\\lPreStmt\\l;";
19685f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek          else if (isa<PostLoad>(Loc))
19697090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek            Out << "\\lPostLoad\\l;";
19707090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek          else if (isa<PostStore>(Loc))
19717090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek            Out << "\\lPostStore\\l";
19727090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek          else if (isa<PostLValue>(Loc))
19737090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek            Out << "\\lPostLValue\\l";
19741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
197510f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#if 0
197610f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek            // FIXME: Replace with a general scheme to determine
197710f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek            // the name of the check.
19788c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek          if (GraphPrintCheckerState->isImplicitNullDeref(N))
19798c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek            Out << "\\|Implicit-Null Dereference.\\l";
19808c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek          else if (GraphPrintCheckerState->isExplicitNullDeref(N))
19818c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek            Out << "\\|Explicit-Null Dereference.\\l";
19828c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek          else if (GraphPrintCheckerState->isUndefDeref(N))
19838c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek            Out << "\\|Dereference of undefialied value.\\l";
19848c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek          else if (GraphPrintCheckerState->isUndefStore(N))
19858c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek            Out << "\\|Store to Undefined Loc.";
19868c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek          else if (GraphPrintCheckerState->isUndefResult(N))
19878c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek            Out << "\\|Result of operation is undefined.";
19888c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek          else if (GraphPrintCheckerState->isNoReturnCall(N))
19898c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek            Out << "\\|Call to function marked \"noreturn\".";
19908c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek          else if (GraphPrintCheckerState->isBadCall(N))
19918c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek            Out << "\\|Call to NULL/Undefined.";
19928c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek          else if (GraphPrintCheckerState->isUndefArg(N))
19938c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek            Out << "\\|Argument in call is undefined";
199410f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#endif
19951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19968c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek          break;
19978c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek        }
19988c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
19999c378f705405d37f49795d5e915989de774fe11fTed Kremenek        const BlockEdge &E = cast<BlockEdge>(Loc);
2000aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek        Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
2001aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek            << E.getDst()->getBlockID()  << ')';
20021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20039c378f705405d37f49795d5e915989de774fe11fTed Kremenek        if (const Stmt *T = E.getSrc()->getTerminator()) {
20041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2005e97ca065c91ff9ca2a2a42eb443eaa553c40441cTed Kremenek          SourceLocation SLoc = T->getLocStart();
20061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2007b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek          Out << "\\|Terminator: ";
2008e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner          LangOptions LO; // FIXME.
2009e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner          E.getSrc()->printTerminator(Out, LO);
20101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20119b5551d7f0209cec8b9c555cf70e893940674e5cTed Kremenek          if (SLoc.isFileID()) {
20129b5551d7f0209cec8b9c555cf70e893940674e5cTed Kremenek            Out << "\\lline="
2013642116259e8df6286063a17361c20e95b5017a0aChandler Carruth              << GraphPrintSourceManager->getExpansionLineNumber(SLoc)
20147da5aea7669e6db3e593162b8a123aef06a04d07Chris Lattner              << " col="
2015a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruth              << GraphPrintSourceManager->getExpansionColumnNumber(SLoc);
20169b5551d7f0209cec8b9c555cf70e893940674e5cTed Kremenek          }
20171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2018daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek          if (isa<SwitchStmt>(T)) {
20199c378f705405d37f49795d5e915989de774fe11fTed Kremenek            const Stmt *Label = E.getDst()->getLabel();
20201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            if (Label) {
20229c378f705405d37f49795d5e915989de774fe11fTed Kremenek              if (const CaseStmt *C = dyn_cast<CaseStmt>(Label)) {
2023daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek                Out << "\\lcase ";
2024e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner                LangOptions LO; // FIXME.
2025e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner                C->getLHS()->printPretty(Out, 0, PrintingPolicy(LO));
20261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20279c378f705405d37f49795d5e915989de774fe11fTed Kremenek                if (const Stmt *RHS = C->getRHS()) {
2028daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek                  Out << " .. ";
2029e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner                  RHS->printPretty(Out, 0, PrintingPolicy(LO));
2030daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek                }
20311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2032daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek                Out << ":";
2033daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek              }
2034daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek              else {
2035daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek                assert (isa<DefaultStmt>(Label));
2036daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek                Out << "\\ldefault:";
2037daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek              }
2038daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek            }
20391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            else
2040daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek              Out << "\\l(implicit) default:";
2041daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek          }
2042daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek          else if (isa<IndirectGotoStmt>(T)) {
2043b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek            // FIXME
2044b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek          }
2045b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek          else {
2046b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek            Out << "\\lCondition: ";
2047b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek            if (*E.getSrc()->succ_begin() == E.getDst())
2048b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek              Out << "true";
2049b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek            else
20501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump              Out << "false";
2051b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek          }
20521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2053b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek          Out << "\\l";
2054b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek        }
20551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
205610f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#if 0
205710f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek          // FIXME: Replace with a general scheme to determine
205810f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek          // the name of the check.
20594a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek        if (GraphPrintCheckerState->isUndefControlFlow(N)) {
20604a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek          Out << "\\|Control-flow based on\\lUndefined value.\\l";
20613b4f6702860208692f6ef28401e68de4e3ff9af9Ted Kremenek        }
206210f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#endif
2063aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek      }
2064aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek    }
20651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20668bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek    ProgramStateRef state = N->getState();
206731ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky    Out << "\\|StateID: " << (const void*) state.getPtr()
206831ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky        << " NodeID: " << (const void*) N << "\\|";
20695eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    state->printDOT(Out);
2070ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek
2071ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek    Out << "\\l";
2072ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek
2073ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek    if (const ProgramPointTag *tag = Loc.getTag()) {
2074ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek      Out << "\\|Tag: " << tag->getTagDescription();
2075ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek      Out << "\\l";
2076ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek    }
2077aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek    return Out.str();
2078aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek  }
2079aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek};
20801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} // end llvm namespace
2081aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek#endif
2082aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek
2083ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek#ifndef NDEBUG
20847ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenektemplate <typename ITERATOR>
20859c378f705405d37f49795d5e915989de774fe11fTed KremenekExplodedNode *GetGraphNode(ITERATOR I) { return *I; }
20867ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenek
2087031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xutemplate <> ExplodedNode*
2088031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing XuGetGraphNode<llvm::DenseMap<ExplodedNode*, Expr*>::iterator>
2089031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  (llvm::DenseMap<ExplodedNode*, Expr*>::iterator I) {
20907ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenek  return I->first;
20917ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenek}
2092ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek#endif
2093ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek
2094d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ViewGraph(bool trim) {
20951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#ifndef NDEBUG
2096ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek  if (trim) {
2097031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu    std::vector<ExplodedNode*> Src;
2098940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek
2099940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek    // Flush any outstanding reports to make sure we cover all the nodes.
2100940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek    // This does not cause them to get displayed.
2101940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek    for (BugReporter::iterator I=BR.begin(), E=BR.end(); I!=E; ++I)
2102940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek      const_cast<BugType*>(*I)->FlushReports(BR);
2103940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek
2104940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek    // Iterate through the reports and get their nodes.
2105404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    for (BugReporter::EQClasses_iterator
2106404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis           EI = BR.EQClasses_begin(), EE = BR.EQClasses_end(); EI != EE; ++EI) {
21074a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer      ExplodedNode *N = const_cast<ExplodedNode*>(EI->begin()->getErrorNode());
2108404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis      if (N) Src.push_back(N);
2109940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek    }
21101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21117ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenek    ViewGraph(&Src[0], &Src[0]+Src.size());
2112ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek  }
2113493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek  else {
2114493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek    GraphPrintCheckerState = this;
2115493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek    GraphPrintSourceManager = &getContext().getSourceManager();
2116ae6814efb6c41bd0c0f6413d25097105284d5be7Ted Kremenek
2117d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis    llvm::ViewGraph(*G.roots_begin(), "ExprEngine");
21181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2119493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek    GraphPrintCheckerState = NULL;
2120493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek    GraphPrintSourceManager = NULL;
2121493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek  }
2122493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek#endif
2123493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek}
2124493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek
2125d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ViewGraph(ExplodedNode** Beg, ExplodedNode** End) {
2126493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek#ifndef NDEBUG
2127493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek  GraphPrintCheckerState = this;
2128493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek  GraphPrintSourceManager = &getContext().getSourceManager();
21291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2130031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  std::auto_ptr<ExplodedGraph> TrimmedG(G.Trim(Beg, End).first);
2131493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek
2132cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  if (!TrimmedG.get())
21336cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer    llvm::errs() << "warning: Trimmed ExplodedGraph is empty.\n";
2134cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  else
2135d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis    llvm::ViewGraph(*TrimmedG->roots_begin(), "TrimmedExprEngine");
21361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21373b4f6702860208692f6ef28401e68de4e3ff9af9Ted Kremenek  GraphPrintCheckerState = NULL;
2138e97ca065c91ff9ca2a2a42eb443eaa553c40441cTed Kremenek  GraphPrintSourceManager = NULL;
2139e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek#endif
2140ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek}
2141