ExprEngine.cpp revision 6960d08b4ddf389d7c81504df7f16dc645120482
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
189b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
19199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck#include "clang/AST/CharUnits.h"
2016f0049415ec596504891259e2a83e19871c0d52Chris Lattner#include "clang/AST/ParentMap.h"
21337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek#include "clang/AST/StmtCXX.h"
2255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/StmtObjC.h"
231b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner#include "clang/Basic/Builtins.h"
240bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek#include "clang/Basic/PrettyStackTrace.h"
2555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/SourceManager.h"
2655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
2755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/CheckerManager.h"
2855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
2955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
306cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer#include "llvm/ADT/ImmutableList.h"
31c2994283aa7538b7420c8e398cde7afa328d7042Anna Zaks#include "llvm/ADT/Statistic.h"
3255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/raw_ostream.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,
27184c484545c5906ba55143e212b4a5275ab55889fJordan Rose                            const LocationContext *LC,
2720b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                            const Stmt *DiagnosticStmt,
2730b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                            ProgramPoint::Kind K) {
2740b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  assert((K == ProgramPoint::PreStmtPurgeDeadSymbolsKind ||
27584c484545c5906ba55143e212b4a5275ab55889fJordan Rose          ReferenceStmt == 0 || isa<ReturnStmt>(ReferenceStmt))
2768501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks          && "PostStmt is not generally supported by the SymbolReaper yet");
27784c484545c5906ba55143e212b4a5275ab55889fJordan Rose  assert(LC && "Must pass the current (or expiring) LocationContext");
27884c484545c5906ba55143e212b4a5275ab55889fJordan Rose
27984c484545c5906ba55143e212b4a5275ab55889fJordan Rose  if (!DiagnosticStmt) {
28084c484545c5906ba55143e212b4a5275ab55889fJordan Rose    DiagnosticStmt = ReferenceStmt;
28184c484545c5906ba55143e212b4a5275ab55889fJordan Rose    assert(DiagnosticStmt && "Required for clearing a LocationContext");
28284c484545c5906ba55143e212b4a5275ab55889fJordan Rose  }
28384c484545c5906ba55143e212b4a5275ab55889fJordan Rose
2840b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  NumRemoveDeadBindings++;
2850b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  CleanedState = Pred->getState();
28684c484545c5906ba55143e212b4a5275ab55889fJordan Rose
28784c484545c5906ba55143e212b4a5275ab55889fJordan Rose  // LC is the location context being destroyed, but SymbolReaper wants a
28884c484545c5906ba55143e212b4a5275ab55889fJordan Rose  // location context that is still live. (If this is the top-level stack
28984c484545c5906ba55143e212b4a5275ab55889fJordan Rose  // frame, this will be null.)
29084c484545c5906ba55143e212b4a5275ab55889fJordan Rose  if (!ReferenceStmt) {
29184c484545c5906ba55143e212b4a5275ab55889fJordan Rose    assert(K == ProgramPoint::PostStmtPurgeDeadSymbolsKind &&
29284c484545c5906ba55143e212b4a5275ab55889fJordan Rose           "Use PostStmtPurgeDeadSymbolsKind for clearing a LocationContext");
29384c484545c5906ba55143e212b4a5275ab55889fJordan Rose    LC = LC->getParent();
29484c484545c5906ba55143e212b4a5275ab55889fJordan Rose  }
29584c484545c5906ba55143e212b4a5275ab55889fJordan Rose
29684c484545c5906ba55143e212b4a5275ab55889fJordan Rose  const StackFrameContext *SFC = LC ? LC->getCurrentStackFrame() : 0;
29784c484545c5906ba55143e212b4a5275ab55889fJordan Rose  SymbolReaper SymReaper(SFC, ReferenceStmt, SymMgr, getStoreManager());
2980b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks
2990b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  getCheckerManager().runCheckersForLiveSymbols(CleanedState, SymReaper);
3000b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks
3010b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  // Create a state in which dead bindings are removed from the environment
3020b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  // and the store. TODO: The function should just return new env and store,
3030b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  // not a new state.
3040b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  CleanedState = StateMgr.removeDeadBindings(CleanedState, SFC, SymReaper);
305241677a13cc46647a8f5098b3e3239bd9480dca2Ted Kremenek
30677d7ef8d8a80ccb2ab3d25c80810571e3ab14ee4Ted Kremenek  // Process any special transfer function for dead symbols.
307f185cc1ac77a84139c603eee3473b88dcb839c68Anna Zaks  // A tag to track convenience transitions, which can be removed at cleanup.
308f185cc1ac77a84139c603eee3473b88dcb839c68Anna Zaks  static SimpleProgramPointTag cleanupTag("ExprEngine : Clean Node");
3096bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks  if (!SymReaper.hasDeadSymbols()) {
3106bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks    // Generate a CleanedNode that has the environment and store cleaned
3116bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks    // up. Since no symbols are dead, we can optimize and not clean out
3126bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks    // the constraint manager.
31366c486f275531df6362b3511fc3af6563561801bTed Kremenek    StmtNodeBuilder Bldr(Pred, Out, *currBldrCtx);
314fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    Bldr.generateNode(DiagnosticStmt, Pred, CleanedState, &cleanupTag, K);
3151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3166bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks  } else {
3176bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks    // Call checkers with the non-cleaned state so that they could query the
3186bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks    // values of the soon to be dead symbols.
319fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose    ExplodedNodeSet CheckedSet;
3200b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks    getCheckerManager().runCheckersForDeadSymbols(CheckedSet, Pred, SymReaper,
3210b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                                                  DiagnosticStmt, *this, K);
322183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
323fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose    // For each node in CheckedSet, generate CleanedNodes that have the
324fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose    // environment, the store, and the constraints cleaned up but have the
325fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose    // user-supplied states as the predecessors.
32666c486f275531df6362b3511fc3af6563561801bTed Kremenek    StmtNodeBuilder Bldr(CheckedSet, Out, *currBldrCtx);
327fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose    for (ExplodedNodeSet::const_iterator
328fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose          I = CheckedSet.begin(), E = CheckedSet.end(); I != E; ++I) {
3298bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek      ProgramStateRef CheckerState = (*I)->getState();
3306bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks
3316bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks      // The constraint manager has not been cleaned up yet, so clean up now.
3326bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks      CheckerState = getConstraintManager().removeDeadBindings(CheckerState,
3336bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks                                                               SymReaper);
3346bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks
3350b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      assert(StateMgr.haveEqualEnvironments(CheckerState, Pred->getState()) &&
3366bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks        "Checkers are not allowed to modify the Environment as a part of "
3376bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks        "checkDeadSymbols processing.");
3380b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      assert(StateMgr.haveEqualStores(CheckerState, Pred->getState()) &&
3396bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks        "Checkers are not allowed to modify the Store as a part of "
3406bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks        "checkDeadSymbols processing.");
3416bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks
3426bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks      // Create a state based on CleanedState with CheckerState GDM and
3436bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks      // generate a transition to that state.
3448bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek      ProgramStateRef CleanedCheckerSt =
3456bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks        StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState);
346fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose      Bldr.generateNode(DiagnosticStmt, *I, CleanedCheckerSt, &cleanupTag, K);
3476bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks    }
34877d7ef8d8a80ccb2ab3d25c80810571e3ab14ee4Ted Kremenek  }
3490b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks}
3500b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks
3510b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaksvoid ExprEngine::ProcessStmt(const CFGStmt S,
3520b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                             ExplodedNode *Pred) {
3530b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  // Reclaim any unnecessary nodes in the ExplodedGraph.
3540b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  G.reclaimRecentlyAllocatedNodes();
3550b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks
35666c486f275531df6362b3511fc3af6563561801bTed Kremenek  currStmt = S.getStmt();
3570b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
35866c486f275531df6362b3511fc3af6563561801bTed Kremenek                                currStmt->getLocStart(),
3590b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                                "Error evaluating statement");
3601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3610b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  // Remove dead bindings and symbols.
3620b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  EntryNode = Pred;
3630b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  ExplodedNodeSet CleanedStates;
3640b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  if (shouldRemoveDeadBindings(AMgr, S, Pred, EntryNode->getLocationContext())){
36584c484545c5906ba55143e212b4a5275ab55889fJordan Rose    removeDead(EntryNode, CleanedStates, currStmt, Pred->getLocationContext());
3660b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  } else
3670b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks    CleanedStates.Add(EntryNode);
3680b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks
3690b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  // Visit the statement.
370dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks  ExplodedNodeSet Dst;
3710b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  for (ExplodedNodeSet::iterator I = CleanedStates.begin(),
3720b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                                 E = CleanedStates.end(); I != E; ++I) {
373dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks    ExplodedNodeSet DstI;
3741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Visit the statement.
37566c486f275531df6362b3511fc3af6563561801bTed Kremenek    Visit(currStmt, *I, DstI);
376dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks    Dst.insert(DstI);
377ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks  }
378ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks
379dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks  // Enqueue the new nodes onto the work list.
38066c486f275531df6362b3511fc3af6563561801bTed Kremenek  Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
3811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
382e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek  // NULL out these variables to cleanup.
383846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek  CleanedState = NULL;
384846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek  EntryNode = NULL;
38566c486f275531df6362b3511fc3af6563561801bTed Kremenek  currStmt = 0;
386e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek}
387e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek
388d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessInitializer(const CFGInitializer Init,
389056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks                                    ExplodedNode *Pred) {
390cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt  const CXXCtorInitializer *BMI = Init.getInitializer();
391563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose
392563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
393563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose                                BMI->getSourceLocation(),
394563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose                                "Error evaluating initializer");
395563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose
39666c486f275531df6362b3511fc3af6563561801bTed Kremenek  // We don't set EntryNode and currStmt. And we don't clean up state.
397056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks  const StackFrameContext *stackFrame =
398056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks                           cast<StackFrameContext>(Pred->getLocationContext());
399056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks  const CXXConstructorDecl *decl =
400056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks                           cast<CXXConstructorDecl>(stackFrame->getDecl());
4013682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose
4023682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  ProgramStateRef State = Pred->getState();
4033a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  SVal thisVal = State->getSVal(svalBuilder.getCXXThis(decl, stackFrame));
4049dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu
4053682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  PostInitializer PP(BMI, stackFrame);
4063682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  ExplodedNodeSet Tmp(Pred);
4073682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose
4083a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  // Evaluate the initializer, if necessary
40900eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet  if (BMI->isAnyMemberInitializer()) {
4103a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose    // Constructors build the object directly in the field,
4113a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose    // but non-objects must be copied in from the initializer.
4123682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose    const Expr *Init = BMI->getInit();
4133682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose    if (!isa<CXXConstructExpr>(Init)) {
4143a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose      SVal FieldLoc;
4153a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose      if (BMI->isIndirectMemberInitializer())
4163a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose        FieldLoc = State->getLValue(BMI->getIndirectMember(), thisVal);
4173a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose      else
4183a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose        FieldLoc = State->getLValue(BMI->getMember(), thisVal);
4193a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose
4203a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose      SVal InitVal = State->getSVal(BMI->getInit(), stackFrame);
4213682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose
4223682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose      Tmp.clear();
4233682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose      evalBind(Tmp, Init, Pred, FieldLoc, InitVal, /*isInit=*/true, &PP);
4243a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose    }
425056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks  } else {
426563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose    assert(BMI->isBaseInitializer() || BMI->isDelegatingInitializer());
427888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose    // We already did all the work when visiting the CXXConstructExpr.
428056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks  }
429dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks
4303682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  // Construct PostInitializer nodes whether the state changed or not,
4313a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  // so that the diagnostics don't get confused.
4323682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  ExplodedNodeSet Dst;
4333682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  NodeBuilder Bldr(Tmp, Dst, *currBldrCtx);
4343682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) {
4353682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose    ExplodedNode *N = *I;
4363682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose    Bldr.generateNode(PP, N->getState(), N);
4373682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  }
4383a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose
439dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks  // Enqueue the new nodes onto the work list.
44066c486f275531df6362b3511fc3af6563561801bTed Kremenek  Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
4419c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu}
4429c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu
443d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D,
444ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks                                     ExplodedNode *Pred) {
445ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks  ExplodedNodeSet Dst;
4463c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek  switch (D.getKind()) {
4474ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu  case CFGElement::AutomaticObjectDtor:
448056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks    ProcessAutomaticObjDtor(cast<CFGAutomaticObjDtor>(D), Pred, Dst);
4494ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu    break;
4504ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu  case CFGElement::BaseDtor:
451056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks    ProcessBaseDtor(cast<CFGBaseDtor>(D), Pred, Dst);
4524ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu    break;
4534ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu  case CFGElement::MemberDtor:
454056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks    ProcessMemberDtor(cast<CFGMemberDtor>(D), Pred, Dst);
4554ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu    break;
4564ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu  case CFGElement::TemporaryDtor:
457056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks    ProcessTemporaryDtor(cast<CFGTemporaryDtor>(D), Pred, Dst);
4584ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu    break;
4594ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu  default:
4604ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu    llvm_unreachable("Unexpected dtor kind.");
4614ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu  }
462ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks
463dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks  // Enqueue the new nodes onto the work list.
46466c486f275531df6362b3511fc3af6563561801bTed Kremenek  Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
4654ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu}
4664ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu
467056c4b46335a3bd2612414735d5749ee159c0165Anna Zaksvoid ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor,
468056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks                                         ExplodedNode *Pred,
469056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks                                         ExplodedNodeSet &Dst) {
4708bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef state = Pred->getState();
471056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks  const VarDecl *varDecl = Dtor.getVarDecl();
4722210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu
4732210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu  QualType varType = varDecl->getType();
4742210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu
4752210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu  if (const ReferenceType *refType = varType->getAs<ReferenceType>())
4762210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu    varType = refType->getPointeeType();
4772210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu
478056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks  Loc dest = state->getLValue(varDecl, Pred->getLocationContext());
479b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu
480888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  VisitCXXDestructor(varType, cast<loc::MemRegionVal>(dest).getRegion(),
481200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose                     Dtor.getTriggerStmt(), /*IsBase=*/false, Pred, Dst);
4824ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu}
4834ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu
484d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessBaseDtor(const CFGBaseDtor D,
485888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose                                 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
486888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  const LocationContext *LCtx = Pred->getLocationContext();
487888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  ProgramStateRef State = Pred->getState();
488888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose
489888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
490888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor,
491888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose                                            LCtx->getCurrentStackFrame());
492888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  SVal ThisVal = Pred->getState()->getSVal(ThisPtr);
493888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose
494888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  // Create the base object region.
495888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  QualType BaseTy = D.getBaseSpecifier()->getType();
496888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, BaseTy);
497888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose
498888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose  VisitCXXDestructor(BaseTy, cast<loc::MemRegionVal>(BaseVal).getRegion(),
499200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose                     CurDtor->getBody(), /*IsBase=*/true, Pred, Dst);
500888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose}
5014ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu
502d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessMemberDtor(const CFGMemberDtor D,
5033a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose                                   ExplodedNode *Pred, ExplodedNodeSet &Dst) {
5043a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  const FieldDecl *Member = D.getFieldDecl();
5053a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  ProgramStateRef State = Pred->getState();
5063a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  const LocationContext *LCtx = Pred->getLocationContext();
5073a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose
5083a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
5093a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  Loc ThisVal = getSValBuilder().getCXXThis(CurDtor,
5103a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose                                            LCtx->getCurrentStackFrame());
5113a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  SVal FieldVal = State->getLValue(Member, cast<Loc>(State->getSVal(ThisVal)));
5123a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose
5133a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose  VisitCXXDestructor(Member->getType(),
5143a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose                     cast<loc::MemRegionVal>(FieldVal).getRegion(),
515200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose                     CurDtor->getBody(), /*IsBase=*/false, Pred, Dst);
5163a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose}
5174ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu
518d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessTemporaryDtor(const CFGTemporaryDtor D,
519056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks                                      ExplodedNode *Pred,
520056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks                                      ExplodedNodeSet &Dst) {}
5219c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu
52248b6247804eacc262cc5508e0fbb74ed819fbb6eJordan Rosevoid ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
5236889679d72859960e0fc8d1080487f63c4df1e0aAnna Zaks                       ExplodedNodeSet &DstTop) {
5240bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
5250bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek                                S->getLocStart(),
5260bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek                                "Error evaluating statement");
5276889679d72859960e0fc8d1080487f63c4df1e0aAnna Zaks  ExplodedNodeSet Dst;
52866c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(Pred, DstTop, *currBldrCtx);
5290bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek
530f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall  // Expressions to ignore.
531f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall  if (const Expr *Ex = dyn_cast<Expr>(S))
532892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    S = Ex->IgnoreParens();
533f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall
534e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek  // FIXME: add metadata to the CFG so that we can disable
535e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek  //  this check when we KNOW that there is no block-level subexpression.
536e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek  //  The motivation is that this check requires a hashtable lookup.
5371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
53866c486f275531df6362b3511fc3af6563561801bTed Kremenek  if (S != currStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(S))
539e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    return;
5401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
541e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek  switch (S->getStmtClass()) {
542f85e193739c953358c865005855253af4f68a497John McCall    // C++ and ARC stuff we don't support yet.
543f85e193739c953358c865005855253af4f68a497John McCall    case Expr::ObjCIndirectCopyRestoreExprClass:
5441b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::CXXDependentScopeMemberExprClass:
5451b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::CXXPseudoDestructorExprClass:
5461b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::CXXTryStmtClass:
5471b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::CXXTypeidExprClass:
5489be88403e965cc49af76c9d33d818781d44b333eFrancois Pichet    case Stmt::CXXUuidofExprClass:
549c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek    case Stmt::CXXUnresolvedConstructExprClass:
5501b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::DependentScopeDeclRefExprClass:
5511b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::UnaryTypeTraitExprClass:
5526ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet    case Stmt::BinaryTypeTraitExprClass:
5534ca8ac2e61c37ddadf37024af86f3e1019af8532Douglas Gregor    case Stmt::TypeTraitExprClass:
55421ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley    case Stmt::ArrayTypeTraitExprClass:
555552622067dc45013d240f73952fece703f5e63bdJohn Wiegley    case Stmt::ExpressionTraitExprClass:
5561b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::UnresolvedLookupExprClass:
557c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek    case Stmt::UnresolvedMemberExprClass:
5586b219d082434394c1ac401390ec1d1967727815aSebastian Redl    case Stmt::CXXNoexceptExprClass:
559be230c36e32142cbdcdbe9c97511d097beeecbabDouglas Gregor    case Stmt::PackExpansionExprClass:
560c7793c73ba8a343de3f2552d984851985a46f159Douglas Gregor    case Stmt::SubstNonTypeTemplateParmPackExprClass:
5619a4db032ecd991626d236a502e770126db32bd31Richard Smith    case Stmt::FunctionParmPackExprClass:
56228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    case Stmt::SEHTryStmtClass:
56328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley    case Stmt::SEHExceptStmtClass:
56401d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor    case Stmt::LambdaExprClass:
565ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks    case Stmt::SEHFinallyStmtClass: {
566fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose      const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState());
56766c486f275531df6362b3511fc3af6563561801bTed Kremenek      Engine.addAbortedBlock(node, currBldrCtx->getBlock());
568c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek      break;
569c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek    }
5705fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek
571f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    case Stmt::ParenExprClass:
572f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall      llvm_unreachable("ParenExprs already handled.");
573f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne    case Stmt::GenericSelectionExprClass:
574f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne      llvm_unreachable("GenericSelectionExprs already handled.");
5751b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    // Cases that should never be evaluated simply because they shouldn't
5761b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    // appear in the CFG.
5771b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::BreakStmtClass:
5781b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::CaseStmtClass:
5791b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::CompoundStmtClass:
5801b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ContinueStmtClass:
58146eaf7789a1059a7b42b7dbd183150c72df5738fTed Kremenek    case Stmt::CXXForRangeStmtClass:
5821b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::DefaultStmtClass:
5831b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::DoStmtClass:
584d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek    case Stmt::ForStmtClass:
5851b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::GotoStmtClass:
586d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek    case Stmt::IfStmtClass:
5871b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::IndirectGotoStmtClass:
5881b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::LabelStmtClass:
589534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    case Stmt::AttributedStmtClass:
5901b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::NoStmtClass:
5911b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::NullStmtClass:
592d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek    case Stmt::SwitchStmtClass:
593d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek    case Stmt::WhileStmtClass:
594ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor    case Expr::MSDependentExistsStmtClass:
5951b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek      llvm_unreachable("Stmt should not be in analyzer evaluation loop");
5961b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek
5974ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose    case Stmt::ObjCSubscriptRefExprClass:
5984ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose    case Stmt::ObjCPropertyRefExprClass:
5994ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose      llvm_unreachable("These are handled by PseudoObjectExpr");
6004ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose
6018ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek    case Stmt::GNUNullExprClass: {
6028f08426e6f54ed20b959018f24dbea106a00b4adJordy Rose      // GNU __null is a pointer-width integer, not an actual pointer.
6038bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek      ProgramStateRef state = Pred->getState();
6045eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek      state = state->BindExpr(S, Pred->getLocationContext(),
6055eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                              svalBuilder.makeIntValWithPtrWidth(0, false));
606ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.generateNode(S, Pred, state);
6078ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek      break;
6088ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek    }
6098ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek
6104beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek    case Stmt::ObjCAtSynchronizedStmtClass:
611ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
6124beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek      VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S), Pred, Dst);
613ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
6144beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek      break;
6154beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek
616ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks    case Stmt::ExprWithCleanupsClass:
617e711d7e7875920fee4180a26bfc67d67f0f71a2cErik Verbruggen      // Handled due to fully linearised CFG.
618f85e193739c953358c865005855253af4f68a497John McCall      break;
619f85e193739c953358c865005855253af4f68a497John McCall
6201b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    // Cases not handled yet; but will handle some day.
6211b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::DesignatedInitExprClass:
6221b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ExtVectorElementExprClass:
6231b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ImaginaryLiteralClass:
6241b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ObjCAtCatchStmtClass:
6251b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ObjCAtFinallyStmtClass:
6261b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ObjCAtTryStmtClass:
627f85e193739c953358c865005855253af4f68a497John McCall    case Stmt::ObjCAutoreleasePoolStmtClass:
6281b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ObjCEncodeExprClass:
6291b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ObjCIsaExprClass:
6301b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ObjCProtocolExprClass:
6311b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ObjCSelectorExprClass:
6321b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ParenListExprClass:
6331b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::PredefinedExprClass:
6341b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::ShuffleVectorExprClass:
6351b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    case Stmt::VAArgExprClass:
636e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne    case Stmt::CUDAKernelCallExprClass:
63756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall    case Stmt::OpaqueValueExprClass:
63861eee0ca33b29e102f11bab77c8b74cc00e2392bTanya Lattner    case Stmt::AsTypeExprClass:
639276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman    case Stmt::AtomicExprClass:
640337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek      // Fall through.
6411b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek
6421b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    // Cases we intentionally don't evaluate, since they don't need
6431b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek    // to be explicitly evaluated.
644bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu    case Stmt::AddrLabelExprClass:
645bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu    case Stmt::IntegerLiteralClass:
646bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu    case Stmt::CharacterLiteralClass:
647c319c585c0d5899cba0dca2272e6e4909c8b9f16Ted Kremenek    case Stmt::ImplicitValueInitExprClass:
648c319c585c0d5899cba0dca2272e6e4909c8b9f16Ted Kremenek    case Stmt::CXXScalarValueInitExprClass:
649477323d58a0de352c6a61e08b5a83127c4adc904Zhongxing Xu    case Stmt::CXXBoolLiteralExprClass:
6501a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek    case Stmt::ObjCBoolLiteralExprClass:
651bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu    case Stmt::FloatingLiteralClass:
652f901a7de97f46ba2b1ff153f9fb83d00dc37cfcfDouglas Gregor    case Stmt::SizeOfPackExprClass:
653e739a29c62c67eaec0af5c4d5c75f9e8f11228bdTed Kremenek    case Stmt::StringLiteralClass:
654e739a29c62c67eaec0af5c4d5c75f9e8f11228bdTed Kremenek    case Stmt::ObjCStringLiteralClass:
655cc2c4b293d8590346f26b7ecc16d299226b8794fTed Kremenek    case Stmt::CXXBindTemporaryExprClass:
656b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose    case Stmt::CXXDefaultArgExprClass:
65769a0e5021c5c49a34aa25cd89b1e613a52097e65Jordan Rose    case Stmt::SubstNonTypeTemplateParmExprClass:
658bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek    case Stmt::CXXNullPtrLiteralExprClass: {
659bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek      Bldr.takeNodes(Pred);
660bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek      ExplodedNodeSet preVisit;
661bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek      getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
662bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek      getCheckerManager().runCheckersForPostStmt(Dst, preVisit, S, *this);
663bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek      Bldr.addNodes(Dst);
664e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
665bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek    }
6661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6671a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek    case Expr::ObjCArrayLiteralClass:
66870fdbc366da85880aae5baebd3351e993ca05603Jordy Rose    case Expr::ObjCDictionaryLiteralClass:
66970fdbc366da85880aae5baebd3351e993ca05603Jordy Rose      // FIXME: explicitly model with a region and the actual contents
67070fdbc366da85880aae5baebd3351e993ca05603Jordy Rose      // of the container.  For now, conjure a symbol.
67170fdbc366da85880aae5baebd3351e993ca05603Jordy Rose    case Expr::ObjCBoxedExprClass: {
6721a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      Bldr.takeNodes(Pred);
6731a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek
6741a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      ExplodedNodeSet preVisit;
6751a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
6761a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek
6771a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      ExplodedNodeSet Tmp;
67866c486f275531df6362b3511fc3af6563561801bTed Kremenek      StmtNodeBuilder Bldr2(preVisit, Tmp, *currBldrCtx);
6791a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek
68070fdbc366da85880aae5baebd3351e993ca05603Jordy Rose      const Expr *Ex = cast<Expr>(S);
68170fdbc366da85880aae5baebd3351e993ca05603Jordy Rose      QualType resultType = Ex->getType();
68270fdbc366da85880aae5baebd3351e993ca05603Jordy Rose
6831a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      for (ExplodedNodeSet::iterator it = preVisit.begin(), et = preVisit.end();
6841a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek           it != et; ++it) {
6851a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek        ExplodedNode *N = *it;
6861a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek        const LocationContext *LCtx = N->getLocationContext();
6873b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek        SVal result = svalBuilder.conjureSymbolVal(0, Ex, LCtx, resultType,
68866c486f275531df6362b3511fc3af6563561801bTed Kremenek                                                   currBldrCtx->blockCount());
6891a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek        ProgramStateRef state = N->getState()->BindExpr(Ex, LCtx, result);
6901a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek        Bldr2.generateNode(S, N, state);
6911a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      }
6921a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek
6931a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
6941a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      Bldr.addNodes(Dst);
6951a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      break;
6961a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek    }
6971a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek
698540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek    case Stmt::ArraySubscriptExprClass:
699ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
700892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      VisitLvalArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst);
701ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
702540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek      break;
7031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
704df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier    case Stmt::GCCAsmStmtClass:
705ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
706df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier      VisitGCCAsmStmt(cast<GCCAsmStmt>(S), Pred, Dst);
707ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
708e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
709b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
7108cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier    case Stmt::MSAsmStmtClass:
7118cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier      Bldr.takeNodes(Pred);
7128cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier      VisitMSAsmStmt(cast<MSAsmStmt>(S), Pred, Dst);
7138cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier      Bldr.addNodes(Dst);
7148cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier      break;
7158cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier
716c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek    case Stmt::BlockExprClass:
717ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
718c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek      VisitBlockExpr(cast<BlockExpr>(S), Pred, Dst);
719ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
720c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek      break;
721c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek
722e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    case Stmt::BinaryOperatorClass: {
72303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu      const BinaryOperator* B = cast<BinaryOperator>(S);
724e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      if (B->isLogicalOp()) {
725ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks        Bldr.takeNodes(Pred);
726e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek        VisitLogicalExpr(B, Pred, Dst);
727ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks        Bldr.addNodes(Dst);
728e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek        break;
729e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      }
7302de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      else if (B->getOpcode() == BO_Comma) {
7318bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek        ProgramStateRef state = Pred->getState();
732ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks        Bldr.generateNode(B, Pred,
7335eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                          state->BindExpr(B, Pred->getLocationContext(),
7345eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                          state->getSVal(B->getRHS(),
7355eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                                  Pred->getLocationContext())));
736e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek        break;
737e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      }
73806fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek
739ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
740ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks
7410caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek      if (AMgr.options.eagerlyAssumeBinOpBifurcation &&
742bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu          (B->isRelationalOp() || B->isEqualityOp())) {
743031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu        ExplodedNodeSet Tmp;
744892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek        VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp);
7450caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek        evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, cast<Expr>(S));
74648af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek      }
74748af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek      else
748892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek        VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
74948af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek
750ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
751e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
752e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    }
75306fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek
754f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose    case Stmt::CXXOperatorCallExprClass: {
755f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose      const CXXOperatorCallExpr *OCE = cast<CXXOperatorCallExpr>(S);
756f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
757f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose      // For instance method operators, make sure the 'this' argument has a
758f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose      // valid region.
759f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose      const Decl *Callee = OCE->getCalleeDecl();
760f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose      if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
761f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose        if (MD->isInstance()) {
762f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose          ProgramStateRef State = Pred->getState();
763f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose          const LocationContext *LCtx = Pred->getLocationContext();
764f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose          ProgramStateRef NewState =
765f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose            createTemporaryRegionIfNeeded(State, LCtx, OCE->getArg(0));
766f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose          if (NewState != State)
767f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose            Pred = Bldr.generateNode(OCE, Pred, NewState, /*Tag=*/0,
768f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose                                     ProgramPoint::PreStmtKind);
769f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose        }
770f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose      }
771f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose      // FALLTHROUGH
772f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose    }
773b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek    case Stmt::CallExprClass:
7749fcce65e7e1307b5b8da9be13e4092d6bb94dc1dRichard Smith    case Stmt::CXXMemberCallExprClass:
7759fcce65e7e1307b5b8da9be13e4092d6bb94dc1dRichard Smith    case Stmt::UserDefinedLiteralClass: {
776ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
777b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek      VisitCallExpr(cast<CallExpr>(S), Pred, Dst);
778ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
77906fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek      break;
780e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    }
781337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek
782337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek    case Stmt::CXXCatchStmtClass: {
783337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek      Bldr.takeNodes(Pred);
784337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek      VisitCXXCatchStmt(cast<CXXCatchStmt>(S), Pred, Dst);
785337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek      Bldr.addNodes(Dst);
786337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek      break;
787337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek    }
78806fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek
789744f1cd66bb6747ea71fbf1172698e7bf35ec88dTed Kremenek    case Stmt::CXXTemporaryObjectExprClass:
790888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose    case Stmt::CXXConstructExprClass: {
791ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
792888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose      VisitCXXConstructExpr(cast<CXXConstructExpr>(S), Pred, Dst);
793ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
7947ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu      break;
7957ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu    }
7967ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu
797856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu    case Stmt::CXXNewExprClass: {
798ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
79903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu      const CXXNewExpr *NE = cast<CXXNewExpr>(S);
800856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu      VisitCXXNewExpr(NE, Pred, Dst);
801ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
802856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu      break;
803856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu    }
804856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu
8056b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu    case Stmt::CXXDeleteExprClass: {
806ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
80703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu      const CXXDeleteExpr *CDE = cast<CXXDeleteExpr>(S);
8086b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu      VisitCXXDeleteExpr(CDE, Pred, Dst);
809ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
8106b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu      break;
8116b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu    }
812e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      // FIXME: ChooseExpr is really a constant.  We need to fix
813e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      //        the CFG do not model them as explicit control-flow.
8141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
815e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    case Stmt::ChooseExprClass: { // __builtin_choose_expr
816ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
8179c378f705405d37f49795d5e915989de774fe11fTed Kremenek      const ChooseExpr *C = cast<ChooseExpr>(S);
818e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
819ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
820e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
821e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    }
8221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
823e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    case Stmt::CompoundAssignOperatorClass:
824ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
825892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
826ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
827e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
828f22679e3e5d5f5754931952e58112b4c863a4137Zhongxing Xu
829f22679e3e5d5f5754931952e58112b4c863a4137Zhongxing Xu    case Stmt::CompoundLiteralExprClass:
830ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
831892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst);
832ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
833f22679e3e5d5f5754931952e58112b4c863a4137Zhongxing Xu      break;
8341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
83556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall    case Stmt::BinaryConditionalOperatorClass:
836e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    case Stmt::ConditionalOperatorClass: { // '?' operator
837ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
83856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      const AbstractConditionalOperator *C
83956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        = cast<AbstractConditionalOperator>(S);
84056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      VisitGuardedExpr(C, C->getTrueExpr(), C->getFalseExpr(), Pred, Dst);
841ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
842e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
843e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    }
8441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
845bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu    case Stmt::CXXThisExprClass:
846ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
847bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu      VisitCXXThisExpr(cast<CXXThisExpr>(S), Pred, Dst);
848ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
849bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu      break;
850bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu
851892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    case Stmt::DeclRefExprClass: {
852ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
853892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      const DeclRefExpr *DE = cast<DeclRefExpr>(S);
854892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      VisitCommonDeclRefExpr(DE, DE->getDecl(), Pred, Dst);
855ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
856e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
857892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    }
8581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
859e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    case Stmt::DeclStmtClass:
860ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
861e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
862ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
863e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
8641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8650835a3cdeefe714b4959d31127ea155e56393125Argyrios Kyrtzidis    case Stmt::ImplicitCastExprClass:
8660d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu    case Stmt::CStyleCastExprClass:
8670d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu    case Stmt::CXXStaticCastExprClass:
8680d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu    case Stmt::CXXDynamicCastExprClass:
8690d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu    case Stmt::CXXReinterpretCastExprClass:
8700d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu    case Stmt::CXXConstCastExprClass:
871f85e193739c953358c865005855253af4f68a497John McCall    case Stmt::CXXFunctionalCastExprClass:
872f85e193739c953358c865005855253af4f68a497John McCall    case Stmt::ObjCBridgedCastExprClass: {
873ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
8749c378f705405d37f49795d5e915989de774fe11fTed Kremenek      const CastExpr *C = cast<CastExpr>(S);
875f85e193739c953358c865005855253af4f68a497John McCall      // Handle the previsit checks.
876f85e193739c953358c865005855253af4f68a497John McCall      ExplodedNodeSet dstPrevisit;
877f85e193739c953358c865005855253af4f68a497John McCall      getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, C, *this);
878f85e193739c953358c865005855253af4f68a497John McCall
879f85e193739c953358c865005855253af4f68a497John McCall      // Handle the expression itself.
880f85e193739c953358c865005855253af4f68a497John McCall      ExplodedNodeSet dstExpr;
881f85e193739c953358c865005855253af4f68a497John McCall      for (ExplodedNodeSet::iterator i = dstPrevisit.begin(),
882f85e193739c953358c865005855253af4f68a497John McCall                                     e = dstPrevisit.end(); i != e ; ++i) {
883f85e193739c953358c865005855253af4f68a497John McCall        VisitCast(C, C->getSubExpr(), *i, dstExpr);
884f85e193739c953358c865005855253af4f68a497John McCall      }
885f85e193739c953358c865005855253af4f68a497John McCall
886f85e193739c953358c865005855253af4f68a497John McCall      // Handle the postvisit checks.
887f85e193739c953358c865005855253af4f68a497John McCall      getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, C, *this);
888ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
889e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
890e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    }
891b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
89203e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor    case Expr::MaterializeTemporaryExprClass: {
893ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
894c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose      const MaterializeTemporaryExpr *MTE = cast<MaterializeTemporaryExpr>(S);
895c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose      CreateCXXTemporaryObject(MTE, Pred, Dst);
896ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
89703e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor      break;
89803e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor    }
89903e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor
900c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu    case Stmt::InitListExprClass:
901ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
902c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu      VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst);
903ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
904c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu      break;
9051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
90697ed4f68f5dba3e21e7a490ef0f9ffd3bfead7f8Ted Kremenek    case Stmt::MemberExprClass:
907ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
908892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst);
909ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
910469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek      break;
911ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks
91297ed4f68f5dba3e21e7a490ef0f9ffd3bfead7f8Ted Kremenek    case Stmt::ObjCIvarRefExprClass:
913ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
914892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      VisitLvalObjCIvarRefExpr(cast<ObjCIvarRefExpr>(S), Pred, Dst);
915ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
91697ed4f68f5dba3e21e7a490ef0f9ffd3bfead7f8Ted Kremenek      break;
917af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek
918af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek    case Stmt::ObjCForCollectionStmtClass:
919ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
920af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek      VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S), Pred, Dst);
921ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
922af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek      break;
9231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
924d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose    case Stmt::ObjCMessageExprClass:
925ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
926d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose      VisitObjCMessage(cast<ObjCMessageExpr>(S), Pred, Dst);
927ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
928e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
9291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
930c32a453e40b2c8878fed10512fb2f570b7aba576Jordan Rose    case Stmt::ObjCAtThrowStmtClass:
931c32a453e40b2c8878fed10512fb2f570b7aba576Jordan Rose    case Stmt::CXXThrowExprClass:
932bbfd07a0c94f659beaf74316029ef73769cefb81Ted Kremenek      // FIXME: This is not complete.  We basically treat @throw as
933bbfd07a0c94f659beaf74316029ef73769cefb81Ted Kremenek      // an abort.
934fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose      Bldr.generateSink(S, Pred, Pred->getState());
935bbfd07a0c94f659beaf74316029ef73769cefb81Ted Kremenek      break;
9361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9371b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    case Stmt::ReturnStmtClass:
938ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
9391b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek      VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst);
940ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
9411b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek      break;
9421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9438ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    case Stmt::OffsetOfExprClass:
944ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
9458ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Pred, Dst);
946ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
9478ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      break;
9488ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
949f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne    case Stmt::UnaryExprOrTypeTraitExprClass:
950ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
951f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne      VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S),
952f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne                                    Pred, Dst);
953ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
954e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
9551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
956e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    case Stmt::StmtExprClass: {
9579c378f705405d37f49795d5e915989de774fe11fTed Kremenek      const StmtExpr *SE = cast<StmtExpr>(S);
958a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek
959a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek      if (SE->getSubStmt()->body_empty()) {
960a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek        // Empty statement expression.
961a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek        assert(SE->getType() == getContext().VoidTy
962a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek               && "Empty statement expression must have void type.");
963a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek        break;
964a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek      }
9651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9669c378f705405d37f49795d5e915989de774fe11fTed Kremenek      if (Expr *LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
9678bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek        ProgramStateRef state = Pred->getState();
968ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks        Bldr.generateNode(SE, Pred,
9695eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                          state->BindExpr(SE, Pred->getLocationContext(),
9705eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                          state->getSVal(LastExpr,
9715eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                                  Pred->getLocationContext())));
972a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek      }
973e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek      break;
974e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek    }
9756987c7b74146b9658b1925c5981f8b0cd0672b55Zhongxing Xu
97672374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek    case Stmt::UnaryOperatorClass: {
977ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.takeNodes(Pred);
97803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu      const UnaryOperator *U = cast<UnaryOperator>(S);
9790caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek      if (AMgr.options.eagerlyAssumeBinOpBifurcation && (U->getOpcode() == UO_LNot)) {
980031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu        ExplodedNodeSet Tmp;
981892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek        VisitUnaryOperator(U, Pred, Tmp);
9820caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek        evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, U);
98372374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek      }
98472374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek      else
985892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek        VisitUnaryOperator(U, Pred, Dst);
986ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks      Bldr.addNodes(Dst);
9871b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek      break;
98872374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek    }
9894b9c2d235fb9449e249d74f48ecfec601650de93John McCall
9904b9c2d235fb9449e249d74f48ecfec601650de93John McCall    case Stmt::PseudoObjectExprClass: {
9914b9c2d235fb9449e249d74f48ecfec601650de93John McCall      Bldr.takeNodes(Pred);
9928bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek      ProgramStateRef state = Pred->getState();
9934b9c2d235fb9449e249d74f48ecfec601650de93John McCall      const PseudoObjectExpr *PE = cast<PseudoObjectExpr>(S);
9944b9c2d235fb9449e249d74f48ecfec601650de93John McCall      if (const Expr *Result = PE->getResultExpr()) {
9955eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek        SVal V = state->getSVal(Result, Pred->getLocationContext());
9965eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek        Bldr.generateNode(S, Pred,
9975eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                          state->BindExpr(S, Pred->getLocationContext(), V));
9984b9c2d235fb9449e249d74f48ecfec601650de93John McCall      }
9994b9c2d235fb9449e249d74f48ecfec601650de93John McCall      else
10005eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek        Bldr.generateNode(S, Pred,
10015eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                          state->BindExpr(S, Pred->getLocationContext(),
10025eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                                   UnknownVal()));
10034b9c2d235fb9449e249d74f48ecfec601650de93John McCall
10044b9c2d235fb9449e249d74f48ecfec601650de93John McCall      Bldr.addNodes(Dst);
10054b9c2d235fb9449e249d74f48ecfec601650de93John McCall      break;
10064b9c2d235fb9449e249d74f48ecfec601650de93John McCall    }
10071b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  }
10081b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek}
10091b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
10105903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaksbool ExprEngine::replayWithoutInlining(ExplodedNode *N,
10115903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks                                       const LocationContext *CalleeLC) {
10125903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  const StackFrameContext *CalleeSF = CalleeLC->getCurrentStackFrame();
10135903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  const StackFrameContext *CallerSF = CalleeSF->getParent()->getCurrentStackFrame();
10145903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  assert(CalleeSF && CallerSF);
10155903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  ExplodedNode *BeforeProcessingCall = 0;
101628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose  const Stmt *CE = CalleeSF->getCallSite();
10175903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
10185903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  // Find the first node before we started processing the call expression.
10195903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  while (N) {
10205903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    ProgramPoint L = N->getLocation();
10215903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    BeforeProcessingCall = N;
10225903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    N = N->pred_empty() ? NULL : *(N->pred_begin());
10235903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
10245903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    // Skip the nodes corresponding to the inlined code.
10255903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    if (L.getLocationContext()->getCurrentStackFrame() != CallerSF)
10265903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      continue;
10275903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    // We reached the caller. Find the node right before we started
102828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose    // processing the call.
10290b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks    if (L.isPurgeKind())
10305903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      continue;
103128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose    if (isa<PreImplicitCall>(&L))
103228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose      continue;
1033852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose    if (isa<CallEnter>(&L))
1034852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose      continue;
10355903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    if (const StmtPoint *SP = dyn_cast<StmtPoint>(&L))
103628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose      if (SP->getStmt() == CE)
10375903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks        continue;
10385903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    break;
10395903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  }
10405903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
1041253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks  if (!BeforeProcessingCall)
10425903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    return false;
10435903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
10445903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  // TODO: Clean up the unneeded nodes.
10455903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
10465903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  // Build an Epsilon node from which we will restart the analyzes.
104728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose  // Note that CE is permitted to be NULL!
10485903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  ProgramPoint NewNodeLoc =
10495903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks               EpsilonPoint(BeforeProcessingCall->getLocationContext(), CE);
10505903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  // Add the special flag to GDM to signal retrying with no inlining.
10515903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  // Note, changing the state ensures that we are not going to cache out.
10525903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  ProgramStateRef NewNodeState = BeforeProcessingCall->getState();
10535903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  NewNodeState = NewNodeState->set<ReplayWithoutInlining>((void*)CE);
10545903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
10555903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  // Make the new node a successor of BeforeProcessingCall.
10565903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  bool IsNew = false;
10575903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  ExplodedNode *NewNode = G.getNode(NewNodeLoc, NewNodeState, false, &IsNew);
1058253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks  // We cached out at this point. Caching out is common due to us backtracking
1059253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks  // from the inlined function, which might spawn several paths.
1060253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks  if (!IsNew)
1061253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks    return true;
1062253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks
10635903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  NewNode->addPredecessor(BeforeProcessingCall, G);
10645903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
10655903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  // Add the new node to the work list.
10665903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  Engine.enqueueStmtNode(NewNode, CalleeSF->getCallSiteBlock(),
10675903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks                                  CalleeSF->getIndex());
10685903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  NumTimesRetriedWithoutInlining++;
10695903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  return true;
10705903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks}
10715903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
1072c03a39e16762627b421247b12a2658be630a3300Anna Zaks/// Block entrance.  (Update counters).
1073253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaksvoid ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
1074b355be838a22a511d078504b2277f70aea52ca85Anna Zaks                                         NodeBuilderWithSinks &nodeBuilder,
1075b355be838a22a511d078504b2277f70aea52ca85Anna Zaks                                         ExplodedNode *Pred) {
107627c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek
107727c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek  // FIXME: Refactor this into a checker.
10782fa9d72d4d23ccdcd4137946e5ebafac7a04f04cTed Kremenek  if (nodeBuilder.getContext().blockCount() >= AMgr.options.maxBlockVisitOnPath) {
1079ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek    static SimpleProgramPointTag tag("ExprEngine : Block count exceeded");
1080253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks    const ExplodedNode *Sink =
1081b355be838a22a511d078504b2277f70aea52ca85Anna Zaks                   nodeBuilder.generateSink(Pred->getState(), Pred, &tag);
1082749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks
1083749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks    // Check if we stopped at the top level function or not.
1084749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks    // Root node should have the location context of the top most function.
1085b355be838a22a511d078504b2277f70aea52ca85Anna Zaks    const LocationContext *CalleeLC = Pred->getLocation().getLocationContext();
10863bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks    const LocationContext *CalleeSF = CalleeLC->getCurrentStackFrame();
10875903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    const LocationContext *RootLC =
10885903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks                        (*G.roots_begin())->getLocation().getLocationContext();
10893bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks    if (RootLC->getCurrentStackFrame() != CalleeSF) {
1090e62f048960645b79363408fdead53fec2a063c52Anna Zaks      Engine.FunctionSummaries->markReachedMaxBlockCount(CalleeSF->getDecl());
10913bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks
10925903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      // Re-run the call evaluation without inlining it, by storing the
10935903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      // no-inlining policy in the state and enqueuing the new work item on
10945903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      // the list. Replay should almost never fail. Use the stats to catch it
10955903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      // if it does.
1096255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek      if ((!AMgr.options.NoRetryExhausted &&
1097b355be838a22a511d078504b2277f70aea52ca85Anna Zaks           replayWithoutInlining(Pred, CalleeLC)))
1098253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks        return;
1099253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks      NumMaxBlockCountReachedInInlined++;
11005903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    } else
1101749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks      NumMaxBlockCountReached++;
1102253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks
1103253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks    // Make sink nodes as exhausted(for stats) only if retry failed.
1104253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks    Engine.blocksExhausted.push_back(std::make_pair(L, Sink));
110527c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek  }
1106e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek}
1107e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek
1108e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===//
1109e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek// Branch processing.
1110e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===//
1111e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek
11126ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// RecoverCastedSymbol - A helper function for ProcessBranch that is used
11136ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// to try to recover some path-sensitivity for casts of symbolic
11146ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// integers that promote their values (which are currently not tracked well).
11156ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// This function returns the SVal bound to Condition->IgnoreCasts if all the
11166ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek//  cast(s) did was sign-extend the original value.
1117294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekstatic SVal RecoverCastedSymbol(ProgramStateManager& StateMgr,
11188bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek                                ProgramStateRef state,
1119294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek                                const Stmt *Condition,
11205eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                const LocationContext *LCtx,
1121294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek                                ASTContext &Ctx) {
11226ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek
112303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const Expr *Ex = dyn_cast<Expr>(Condition);
11246ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek  if (!Ex)
11256ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek    return UnknownVal();
11266ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek
11276ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek  uint64_t bits = 0;
11286ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek  bool bitsInit = false;
11291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
113003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  while (const CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
11316ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek    QualType T = CE->getType();
11326ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek
11336ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek    if (!T->isIntegerType())
11346ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek      return UnknownVal();
11351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11366ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek    uint64_t newBits = Ctx.getTypeSize(T);
11376ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek    if (!bitsInit || newBits < bits) {
11386ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek      bitsInit = true;
11396ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek      bits = newBits;
11406ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek    }
11411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11426ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek    Ex = CE->getSubExpr();
11436ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek  }
11446ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek
11456ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek  // We reached a non-cast.  Is it a symbolic value?
11466ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek  QualType T = Ex->getType();
11476ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek
11486ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek  if (!bitsInit || !T->isIntegerType() || Ctx.getTypeSize(T) > bits)
11496ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek    return UnknownVal();
11501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11515eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  return state->getSVal(Ex, LCtx);
11526ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek}
11536ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek
11543f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenekstatic const Stmt *ResolveCondition(const Stmt *Condition,
11553f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek                                    const CFGBlock *B) {
11563f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  if (const Expr *Ex = dyn_cast<Expr>(Condition))
11573f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    Condition = Ex->IgnoreParens();
11583f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek
11593f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  const BinaryOperator *BO = dyn_cast<BinaryOperator>(Condition);
11603f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  if (!BO || !BO->isLogicalOp())
11613f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    return Condition;
11623f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek
11633f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  // For logical operations, we still have the case where some branches
11643f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  // use the traditional "merge" approach and others sink the branch
11653f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  // directly into the basic blocks representing the logical operation.
11663f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  // We need to distinguish between those two cases here.
11673f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek
11683f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  // The invariants are still shifting, but it is possible that the
11693f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  // last element in a CFGBlock is not a CFGStmt.  Look for the last
11703f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  // CFGStmt as the value of the condition.
11713f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  CFGBlock::const_reverse_iterator I = B->rbegin(), E = B->rend();
11723f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  for (; I != E; ++I) {
11733f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    CFGElement Elem = *I;
11743f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    CFGStmt *CS = dyn_cast<CFGStmt>(&Elem);
11753f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    if (!CS)
11763f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek      continue;
11773f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    if (CS->getStmt() != Condition)
11783f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek      break;
11793f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    return Condition;
11803f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  }
11813f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek
11823f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  assert(I != E);
11833f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek
11843f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  while (Condition) {
11853f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    BO = dyn_cast<BinaryOperator>(Condition);
11863f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    if (!BO || !BO->isLogicalOp())
11873f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek      return Condition;
11883f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    Condition = BO->getRHS()->IgnoreParens();
11893f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  }
11903f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  llvm_unreachable("could not resolve condition");
11913f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek}
11923f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek
11939c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
1194a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks                               NodeBuilderContext& BldCtx,
1195ad62deeb70e97da6bd514dd390ea1ce6af6ad81dAnna Zaks                               ExplodedNode *Pred,
11961aae01a8308d2f8e31adab3f4d7ac35543aac680Anna Zaks                               ExplodedNodeSet &Dst,
1197a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks                               const CFGBlock *DstT,
1198a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks                               const CFGBlock *DstF) {
119966c486f275531df6362b3511fc3af6563561801bTed Kremenek  currBldrCtx = &BldCtx;
1200f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks
1201b2331834a0515c80862ee51325c758a053829f15Ted Kremenek  // Check for NULL conditions; e.g. "for(;;)"
12021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (!Condition) {
12031aae01a8308d2f8e31adab3f4d7ac35543aac680Anna Zaks    BranchNodeBuilder NullCondBldr(Pred, Dst, BldCtx, DstT, DstF);
1204a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks    NullCondBldr.markInfeasible(false);
12054e82d3cf6fd4c907265e3fa3aac0a835c35dc759Anna Zaks    NullCondBldr.generateNode(Pred->getState(), true, Pred);
1206b2331834a0515c80862ee51325c758a053829f15Ted Kremenek    return;
1207b2331834a0515c80862ee51325c758a053829f15Ted Kremenek  }
12081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12093f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek
12103f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  // Resolve the condition in the precense of nested '||' and '&&'.
12113f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  if (const Expr *Ex = dyn_cast<Expr>(Condition))
12123f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek    Condition = Ex->IgnoreParens();
12133f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek
12143f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek  Condition = ResolveCondition(Condition, BldCtx.getBlock());
121521028dd8850c64a414f7a82dfddcc291351203d6Ted Kremenek  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
121621028dd8850c64a414f7a82dfddcc291351203d6Ted Kremenek                                Condition->getLocStart(),
121721028dd8850c64a414f7a82dfddcc291351203d6Ted Kremenek                                "Error evaluating branch");
12180fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek
1219f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks  ExplodedNodeSet CheckersOutSet;
1220f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks  getCheckerManager().runCheckersForBranchCondition(Condition, CheckersOutSet,
12214e82d3cf6fd4c907265e3fa3aac0a835c35dc759Anna Zaks                                                    Pred, *this);
12228ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks  // We generated only sinks.
1223f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks  if (CheckersOutSet.empty())
12248ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks    return;
12251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1226f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks  BranchNodeBuilder builder(CheckersOutSet, Dst, BldCtx, DstT, DstF);
1227f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks  for (NodeBuilder::iterator I = CheckersOutSet.begin(),
1228f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks                             E = CheckersOutSet.end(); E != I; ++I) {
1229cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    ExplodedNode *PredI = *I;
1230cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks
1231cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    if (PredI->isSink())
1232cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks      continue;
1233cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks
12348bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek    ProgramStateRef PrevState = Pred->getState();
12355eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    SVal X = PrevState->getSVal(Condition, Pred->getLocationContext());
1236cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks
1237cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    if (X.isUnknownOrUndef()) {
1238cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks      // Give it a chance to recover from unknown.
1239cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks      if (const Expr *Ex = dyn_cast<Expr>(Condition)) {
1240cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks        if (Ex->getType()->isIntegerType()) {
1241cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks          // Try to recover some path-sensitivity.  Right now casts of symbolic
1242cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks          // integers that promote their values are currently not tracked well.
1243cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks          // If 'Condition' is such an expression, try and recover the
1244cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks          // underlying value and use that instead.
1245cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks          SVal recovered = RecoverCastedSymbol(getStateManager(),
1246cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks                                               PrevState, Condition,
12475eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                               Pred->getLocationContext(),
1248cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks                                               getContext());
1249cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks
1250cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks          if (!recovered.isUnknown()) {
1251cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks            X = recovered;
1252cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks          }
12530835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu        }
1254b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek      }
12550835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu    }
12565eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek
12570835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu    // If the condition is still unknown, give up.
125873c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis    if (X.isUnknownOrUndef()) {
1259829846b5002d7f8d6a54b9c58c3ecf7cac56d2ccTed Kremenek      builder.generateNode(PrevState, true, PredI);
1260829846b5002d7f8d6a54b9c58c3ecf7cac56d2ccTed Kremenek      builder.generateNode(PrevState, false, PredI);
1261cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks      continue;
12621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
12631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1264cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    DefinedSVal V = cast<DefinedSVal>(X);
12650835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu
12666960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose    ProgramStateRef StTrue, StFalse;
12676960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose    tie(StTrue, StFalse) = PrevState->assume(V);
12686960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose
1269cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    // Process the true branch.
1270cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    if (builder.isFeasible(true)) {
12716960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose      if (StTrue)
12726960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose        builder.generateNode(StTrue, true, PredI);
1273cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks      else
1274cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks        builder.markInfeasible(true);
1275cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    }
12761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1277cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    // Process the false branch.
1278cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    if (builder.isFeasible(false)) {
12796960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose      if (StFalse)
12806960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose        builder.generateNode(StFalse, false, PredI);
1281cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks      else
1282cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks        builder.markInfeasible(false);
1283cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks    }
1284cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks  }
128566c486f275531df6362b3511fc3af6563561801bTed Kremenek  currBldrCtx = 0;
1286f233d48cfc513b045e2c2cfca5c175220fbd0a82Ted Kremenek}
1287f233d48cfc513b045e2c2cfca5c175220fbd0a82Ted Kremenek
1288e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek/// processIndirectGoto - Called by CoreEngine.  Used to generate successor
1289754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek///  nodes by processing the 'effects' of a computed goto jump.
1290ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattnervoid ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) {
1291754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek
12928bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef state = builder.getState();
12935eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  SVal V = state->getSVal(builder.getTarget(), builder.getLocationContext());
12941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1295754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  // Three possibilities:
1296754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  //
1297754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  //   (1) We know the computed label.
12984a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek  //   (2) The label is NULL (or some other constant), or Undefined.
1299754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  //   (3) We have no clue about the label.  Dispatch to all targets.
1300754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  //
13011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1302d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  typedef IndirectGotoNodeBuilder::iterator iterator;
1303754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek
13041c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  if (isa<loc::GotoLabel>(V)) {
1305ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner    const LabelDecl *L = cast<loc::GotoLabel>(V).getLabel();
13061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1307ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner    for (iterator I = builder.begin(), E = builder.end(); I != E; ++I) {
130824f1a967741ff9f8025ee23be12ba6feacc31f77Ted Kremenek      if (I.getLabel() == L) {
1309a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek        builder.generateNode(I, state);
1310754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek        return;
1311754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek      }
1312754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek    }
13131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1314b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie    llvm_unreachable("No block with label.");
1315754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  }
1316754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek
13171c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  if (isa<loc::ConcreteInt>(V) || isa<UndefinedVal>(V)) {
1318754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek    // Dispatch to the first target and mark it as a sink.
13192055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu    //ExplodedNode* N = builder.generateNode(builder.begin(), state, true);
13202055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu    // FIXME: add checker visit.
13212055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu    //    UndefBranches.insert(N);
1322754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek    return;
1323754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  }
13241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1325754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  // This is really a catch-all.  We don't support symbolics yet.
1326b3cfd58c9b13325d994e5f9b5065e6a22d91911dTed Kremenek  // FIXME: Implement dispatch for symbolic pointers.
13271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1328754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  for (iterator I=builder.begin(), E=builder.end(); I != E; ++I)
1329a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek    builder.generateNode(I, state);
1330754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek}
1331f233d48cfc513b045e2c2cfca5c175220fbd0a82Ted Kremenek
1332d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis/// ProcessEndPath - Called by CoreEngine.  Used to generate end-of-path
133373099bfea9f5d4ec05265170bbefec3d76fb6b5eTed Kremenek///  nodes when the control reaches the end of a function.
1334b355be838a22a511d078504b2277f70aea52ca85Anna Zaksvoid ExprEngine::processEndOfFunction(NodeBuilderContext& BC,
1335b355be838a22a511d078504b2277f70aea52ca85Anna Zaks                                      ExplodedNode *Pred) {
1336b355be838a22a511d078504b2277f70aea52ca85Anna Zaks  StateMgr.EndPath(Pred->getState());
13378501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks
1338af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks  ExplodedNodeSet Dst;
13398501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks  if (Pred->getLocationContext()->inTopFrame()) {
13408501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks    // Remove dead symbols.
13418501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks    ExplodedNodeSet AfterRemovedDead;
13428501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks    removeDeadOnEndOfFunction(BC, Pred, AfterRemovedDead);
13438501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks
13448501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks    // Notify checkers.
13458501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks    for (ExplodedNodeSet::iterator I = AfterRemovedDead.begin(),
13468501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks        E = AfterRemovedDead.end(); I != E; ++I) {
13478501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks      getCheckerManager().runCheckersForEndPath(BC, Dst, *I, *this);
13488501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks    }
13498501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks  } else {
13508501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks    getCheckerManager().runCheckersForEndPath(BC, Dst, Pred, *this);
13518501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks  }
13528501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks
13534d2ae4a70336dc2aa11389b34946be152bb454c9Anna Zaks  Engine.enqueueEndOfFunction(Dst);
135473099bfea9f5d4ec05265170bbefec3d76fb6b5eTed Kremenek}
135573099bfea9f5d4ec05265170bbefec3d76fb6b5eTed Kremenek
1356d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis/// ProcessSwitch - Called by CoreEngine.  Used to generate successor
1357daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek///  nodes by processing the 'effects' of a switch statement.
1358e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenekvoid ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
1359d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  typedef SwitchNodeBuilder::iterator iterator;
13608bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef state = builder.getState();
13619c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const Expr *CondE = builder.getCondition();
13625eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  SVal  CondV_untested = state->getSVal(CondE, builder.getLocationContext());
1363daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek
13645b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  if (CondV_untested.isUndef()) {
13652055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu    //ExplodedNode* N = builder.generateDefaultCaseNode(state, true);
1366b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek    // FIXME: add checker
13672055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu    //UndefBranches.insert(N);
13682055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu
1369daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek    return;
1370daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek  }
13715b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek  DefinedOrUnknownSVal CondV = cast<DefinedOrUnknownSVal>(CondV_untested);
1372692416c214a3b234236dedcf875735a9cc29e90bTed Kremenek
13738bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef DefaultSt = state;
137434feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek
137534feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek  iterator I = builder.begin(), EI = builder.end();
137634feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek  bool defaultIsFeasible = I == EI;
13771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
137834feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek  for ( ; I != EI; ++I) {
1379e71f3d587844110d836c82250830b27b1651afdbTed Kremenek    // Successor may be pruned out during CFG construction.
1380e71f3d587844110d836c82250830b27b1651afdbTed Kremenek    if (!I.getBlock())
1381e71f3d587844110d836c82250830b27b1651afdbTed Kremenek      continue;
1382e71f3d587844110d836c82250830b27b1651afdbTed Kremenek
13839c378f705405d37f49795d5e915989de774fe11fTed Kremenek    const CaseStmt *Case = I.getCase();
138472afb3739da0da02158242ae41a50cfe0bea78b4Ted Kremenek
138572afb3739da0da02158242ae41a50cfe0bea78b4Ted Kremenek    // Evaluate the LHS of the case value.
138685df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith    llvm::APSInt V1 = Case->getLHS()->EvaluateKnownConstInt(getContext());
138785df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith    assert(V1.getBitWidth() == getContext().getTypeSize(CondE->getType()));
13881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1389daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek    // Get the RHS of the case, if it exists.
139085df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith    llvm::APSInt V2;
139185df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith    if (const Expr *E = Case->getRHS())
139285df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith      V2 = E->EvaluateKnownConstInt(getContext());
139314a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek    else
139414a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek      V2 = V1;
13951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1396daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek    // FIXME: Eventually we should replace the logic below with a range
1397daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek    //  comparison, rather than concretize the values within the range.
1398aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek    //  This should be easy once we have "ranges" for NonLVals.
13991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
140014a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek    do {
140185df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith      nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1));
14029c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek      DefinedOrUnknownSVal Res = svalBuilder.evalEQ(DefaultSt ? DefaultSt : state,
140348569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek                                               CondV, CaseVal);
1404b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
14051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      // Now "assume" that the case matches.
14068bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek      if (ProgramStateRef stateNew = state->assume(Res, true)) {
1407a591bc04d21fa62ebffcb2c7814d738ca8f5e2f9Ted Kremenek        builder.generateCaseStmtNode(I, stateNew);
14081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1409daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek        // If CondV evaluates to a constant, then we know that this
1410daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek        // is the *only* case that we can take, so stop evaluating the
1411daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek        // others.
14121c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu        if (isa<nonloc::ConcreteInt>(CondV))
1413daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek          return;
1414daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek      }
14151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1416daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek      // Now "assume" that the case doesn't match.  Add this state
1417daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek      // to the default state (if it is feasible).
141848569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek      if (DefaultSt) {
14198bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek        if (ProgramStateRef stateNew = DefaultSt->assume(Res, false)) {
142048569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek          defaultIsFeasible = true;
142148569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek          DefaultSt = stateNew;
142248569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek        }
142348569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek        else {
142448569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek          defaultIsFeasible = false;
142548569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek          DefaultSt = NULL;
142648569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek        }
14275014ab113eb211b8320ae30b173d7020352663c6Ted Kremenek      }
1428b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
142914a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek      // Concretize the next value in the range.
143085df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith      if (V1 == V2)
143114a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek        break;
14321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
143385df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith      ++V1;
143485df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith      assert (V1 <= V2);
14351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
143614a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek    } while (true);
1437daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek  }
14381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14394d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  if (!defaultIsFeasible)
14404d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek    return;
14414d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek
14424d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  // If we have switch(enum value), the default branch is not
14434d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  // feasible if all of the enum constants not covered by 'case:' statements
14444d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  // are not feasible values for the switch condition.
14454d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  //
14464d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  // Note that this isn't as accurate as it could be.  Even if there isn't
14474d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  // a case for a particular enum value as long as that enum value isn't
14484d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  // feasible then it shouldn't be considered for making 'default:' reachable.
14494d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  const SwitchStmt *SS = builder.getSwitch();
14504d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  const Expr *CondExpr = SS->getCond()->IgnoreParenImpCasts();
14514d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  if (CondExpr->getType()->getAs<EnumType>()) {
14524d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek    if (SS->isAllEnumCasesCovered())
14534d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek      return;
14544d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  }
14554d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek
14564d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  builder.generateDefaultCaseNode(DefaultSt);
1457daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek}
1458daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek
1459e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===//
1460ec96a2d52d16e150baaf629cd35e3fabff5d8915Ted Kremenek// Transfer functions: Loads and stores.
1461e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===//
1462d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek
1463d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D,
1464d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis                                        ExplodedNode *Pred,
1465d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis                                        ExplodedNodeSet &Dst) {
146666c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
1467ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks
14688bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef state = Pred->getState();
14695eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  const LocationContext *LCtx = Pred->getLocationContext();
14706d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu
14719c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1472591b5f53c0e11d87401b4804bb1be1a53f95c619Anna Zaks    assert(Ex->isGLValue());
1473d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek    SVal V = state->getLValue(VD, Pred->getLocationContext());
1474a7581731b1453b51b26154d2409d42a5b6395079Zhongxing Xu
1475892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    // For references, the 'lvalue' is the pointer address stored in the
1476892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    // reference region.
1477892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    if (VD->getType()->isReferenceType()) {
1478892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      if (const MemRegion *R = V.getAsRegion())
1479892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek        V = state->getSVal(R);
1480892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      else
1481892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek        V = UnknownVal();
1482852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek    }
14836d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu
1484fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0,
1485ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks                      ProgramPoint::PostLValueKind);
1486852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek    return;
1487892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek  }
14889c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (const EnumConstantDecl *ED = dyn_cast<EnumConstantDecl>(D)) {
1489591b5f53c0e11d87401b4804bb1be1a53f95c619Anna Zaks    assert(!Ex->isGLValue());
1490c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    SVal V = svalBuilder.makeIntVal(ED->getInitVal());
14915eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V));
14926d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu    return;
1493892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek  }
14949c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1495c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    SVal V = svalBuilder.getFunctionPointer(FD);
1496fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0,
1497ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks                      ProgramPoint::PostLValueKind);
14986d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu    return;
14991b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  }
15005aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek  if (isa<FieldDecl>(D)) {
1501fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    // FIXME: Compute lvalue of field pointers-to-member.
15020156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose    // Right now we just use a non-null void pointer, so that it gives proper
15030156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose    // results in boolean contexts.
15040156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose    SVal V = svalBuilder.conjureSymbolVal(Ex, LCtx, getContext().VoidPtrTy,
15050156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose                                          currBldrCtx->blockCount());
15060156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose    state = state->assume(cast<DefinedOrUnknownSVal>(V), true);
15070156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0,
1508fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose		      ProgramPoint::PostLValueKind);
15095aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek    return;
15105aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek  }
15115aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek
1512fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose  llvm_unreachable("Support for this Decl not implemented.");
15133271f8d315712885ac87747369bb1d9f4b1ea81fTed Kremenek}
15143271f8d315712885ac87747369bb1d9f4b1ea81fTed Kremenek
1515540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek/// VisitArraySubscriptExpr - Transfer function for array accesses
15169c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *A,
15179c378f705405d37f49795d5e915989de774fe11fTed Kremenek                                             ExplodedNode *Pred,
15189c378f705405d37f49795d5e915989de774fe11fTed Kremenek                                             ExplodedNodeSet &Dst){
15191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15209c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const Expr *Base = A->getBase()->IgnoreParens();
15219c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const Expr *Idx  = A->getIdx()->IgnoreParens();
1522892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek
15231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15248f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek  ExplodedNodeSet checkerPreStmt;
15258f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek  getCheckerManager().runCheckersForPreStmt(checkerPreStmt, Pred, A, *this);
15268f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek
152766c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(checkerPreStmt, Dst, *currBldrCtx);
1528ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks
15298f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek  for (ExplodedNodeSet::iterator it = checkerPreStmt.begin(),
15308f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek                                 ei = checkerPreStmt.end(); it != ei; ++it) {
15315eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    const LocationContext *LCtx = (*it)->getLocationContext();
15328bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek    ProgramStateRef state = (*it)->getState();
15335eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    SVal V = state->getLValue(A->getType(),
15345eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                              state->getSVal(Idx, LCtx),
15355eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                              state->getSVal(Base, LCtx));
1536591b5f53c0e11d87401b4804bb1be1a53f95c619Anna Zaks    assert(A->isGLValue());
1537fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    Bldr.generateNode(A, *it, state->BindExpr(A, LCtx, V), 0,
1538fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose                      ProgramPoint::PostLValueKind);
15391b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  }
1540540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek}
1541540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek
1542469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek/// VisitMemberExpr - Transfer function for member expressions.
15439c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
15446889679d72859960e0fc8d1080487f63c4df1e0aAnna Zaks                                 ExplodedNodeSet &TopDst) {
15451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
154666c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(Pred, TopDst, *currBldrCtx);
15476889679d72859960e0fc8d1080487f63c4df1e0aAnna Zaks  ExplodedNodeSet Dst;
1548603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose  ValueDecl *Member = M->getMemberDecl();
154910f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek
1550603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose  // Handle static member variables and enum constants accessed via
1551603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose  // member syntax.
1552603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose  if (isa<VarDecl>(Member) || isa<EnumConstantDecl>(Member)) {
1553ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks    Bldr.takeNodes(Pred);
1554603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose    VisitCommonDeclRefExpr(M, Member, Pred, Dst);
1555ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks    Bldr.addNodes(Dst);
15565bd04952d4ae7ca894f583583208f0cec4735a90Ted Kremenek    return;
15575bd04952d4ae7ca894f583583208f0cec4735a90Ted Kremenek  }
155810f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek
1559f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  ProgramStateRef state = Pred->getState();
1560f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  const LocationContext *LCtx = Pred->getLocationContext();
1561f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  Expr *BaseExpr = M->getBase();
1562f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose
156310f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek  // Handle C++ method calls.
1564603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) {
1565f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose    if (MD->isInstance())
1566f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose      state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
156710f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek
1568f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose    SVal MDVal = svalBuilder.getFunctionPointer(MD);
1569f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose    state = state->BindExpr(M, LCtx, MDVal);
157020aa40342bd74895128860c081aa84cd85bfa68dJordan Rose
1571f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose    Bldr.generateNode(M, Pred, state);
1572ce6644bc1e921833f9b3c10cf7d4a0b78e8d5dc9Jordan Rose    return;
157320aa40342bd74895128860c081aa84cd85bfa68dJordan Rose  }
157420aa40342bd74895128860c081aa84cd85bfa68dJordan Rose
1575f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  // Handle regular struct fields / member variables.
1576f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
1577f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose  SVal baseExprVal = state->getSVal(BaseExpr, LCtx);
1578d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose
1579603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose  FieldDecl *field = cast<FieldDecl>(Member);
1580e3939d7446959afb6b650fe08e952d0f64ab6794Ted Kremenek  SVal L = state->getLValue(field, baseExprVal);
15816b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose  if (M->isGLValue()) {
15826b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose    if (field->getType()->isReferenceType()) {
1583d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose      if (const MemRegion *R = L.getAsRegion())
1584d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose        L = state->getSVal(R);
1585d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose      else
15866b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose        L = UnknownVal();
15876b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose    }
15886b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose
1589d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose    Bldr.generateNode(M, Pred, state->BindExpr(M, LCtx, L), 0,
1590d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose                      ProgramPoint::PostLValueKind);
15916b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose  } else {
1592ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks    Bldr.takeNodes(Pred);
1593bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek    evalLoad(Dst, M, M, Pred, state, L);
1594ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks    Bldr.addNodes(Dst);
1595ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks  }
1596469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek}
1597469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek
15989c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek/// evalBind - Handle the semantics of binding a value to a specific location.
15999c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek///  This method is used by evalStore and (soon) VisitDeclStmt, and others.
16009c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
160193bd5ca766c4d7906878f4ffe76ce1b2080e540bJordy Rose                          ExplodedNode *Pred,
160232a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek                          SVal location, SVal Val,
16033682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose                          bool atDeclInit, const ProgramPoint *PP) {
16043682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose
16053682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  const LocationContext *LC = Pred->getLocationContext();
16063682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  PostStmt PS(StoreE, LC);
16073682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose  if (!PP)
16083682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose    PP = &PS;
1609b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
1610b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek  // Do a previsit of the bind.
1611fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose  ExplodedNodeSet CheckedSet;
1612fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose  getCheckerManager().runCheckersForBind(CheckedSet, Pred, location, Val,
16133682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose                                         StoreE, *this, *PP);
1614b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
161532a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek  // If the location is not a 'Loc', it will already be handled by
161632a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek  // the checkers.  There is nothing left to do.
161732a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek  if (!isa<Loc>(location)) {
161832a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek    Dst = CheckedSet;
161932a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek    return;
162032a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek  }
162132a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek
16226b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks  ExplodedNodeSet TmpDst;
162366c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(CheckedSet, TmpDst, *currBldrCtx);
16246b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks
1625b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek  for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
1626b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek       I!=E; ++I) {
16273d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    ExplodedNode *PredI = *I;
16283d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    ProgramStateRef state = PredI->getState();
162932a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek
163032a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek    // When binding the value, pass on the hint that this is a initialization.
163132a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek    // For initializations, we do not need to inform clients of region
163232a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek    // changes.
163332a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek    state = state->bindLoc(cast<Loc>(location),
163432a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek                           Val, /* notifyChanges = */ !atDeclInit);
163532a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek
16363d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    const MemRegion *LocReg = 0;
163732a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek    if (loc::MemRegionVal *LocRegVal = dyn_cast<loc::MemRegionVal>(&location)) {
16383d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks      LocReg = LocRegVal->getRegion();
163932a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek    }
16403682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose
16413d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    const ProgramPoint L = PostStore(StoreE, LC, LocReg, 0);
1642fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    Bldr.generateNode(L, state, PredI);
1643b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek  }
16446b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks  Dst.insert(TmpDst);
1645a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek}
1646a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek
16479c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek/// evalStore - Handle the semantics of a store via an assignment.
1648a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek///  @param Dst The node set to store generated state nodes
16492e6f5b823912ae76211427cb8684c9eaa6e53a1fJames Dennett///  @param AssignE The assignment expression if the store happens in an
1650e8a4d7d0064b357a30fe7ee4f2ddc02f9ffc0357Zhongxing Xu///         assignment.
16512e6f5b823912ae76211427cb8684c9eaa6e53a1fJames Dennett///  @param LocationE The location expression that is stored to.
1652a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek///  @param state The current simulation state
1653a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek///  @param location The location to store the value
1654a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek///  @param Val The value to be stored
16559c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE,
16569c378f705405d37f49795d5e915989de774fe11fTed Kremenek                             const Expr *LocationE,
16579c378f705405d37f49795d5e915989de774fe11fTed Kremenek                             ExplodedNode *Pred,
16588bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek                             ProgramStateRef state, SVal location, SVal Val,
1659ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek                             const ProgramPointTag *tag) {
166014429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis  // Proceed with the store.  We use AssignE as the anchor for the PostStore
166114429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis  // ProgramPoint if it is non-NULL, and LocationE otherwise.
166214429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis  const Expr *StoreE = AssignE ? AssignE : LocationE;
166314429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis
16641b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  // Evaluate the location (checks for bad dereferences).
1665b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  ExplodedNodeSet Tmp;
1666bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek  evalLocation(Tmp, AssignE, LocationE, Pred, state, location, tag, false);
16671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1668b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  if (Tmp.empty())
16691b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    return;
1670b0533965f1b4db020692e3b23ca7b3bc15bf5897Ted Kremenek
167173c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis  if (location.isUndef())
167273c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis    return;
1673a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek
1674b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI)
16753d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    evalBind(Dst, StoreE, *NI, location, Val, false);
16761b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek}
16771b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
1678bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenekvoid ExprEngine::evalLoad(ExplodedNodeSet &Dst,
1679bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                          const Expr *NodeEx,
1680bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                          const Expr *BoundEx,
1681bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                          ExplodedNode *Pred,
1682bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                          ProgramStateRef state,
1683bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                          SVal location,
1684bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                          const ProgramPointTag *tag,
1685bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                          QualType LoadTy)
1686bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek{
1687cca8ab155e8c20b98ba2d90eb2b1c228895e06fdZhanyong Wan  assert(!isa<NonLoc>(location) && "location cannot be a NonLoc.");
168814429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis
16895b8c69494881b7d35bc6244b4a19be0cc2eab368Jordan Rose  // Are we loading from a region?  This actually results in two loads; one
1690852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  // to fetch the address of the referenced value and one to fetch the
1691852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  // referenced value.
16929697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek  if (const TypedValueRegion *TR =
16939697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek        dyn_cast_or_null<TypedValueRegion>(location.getAsRegion())) {
1694b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
1695018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu    QualType ValTy = TR->getValueType();
1696852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek    if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) {
1697ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek      static SimpleProgramPointTag
1698ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek             loadReferenceTag("ExprEngine : Load Reference");
1699852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek      ExplodedNodeSet Tmp;
1700bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek      evalLoadCommon(Tmp, NodeEx, BoundEx, Pred, state,
1701bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                     location, &loadReferenceTag,
1702852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek                     getContext().getPointerType(RT->getPointeeType()));
1703852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek
1704852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek      // Perform the load from the referenced value.
1705852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end() ; I!=E; ++I) {
1706db5e8cd095d1ffdd18f5620ad2348b5f386bebe3Anna Zaks        state = (*I)->getState();
1707bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek        location = state->getSVal(BoundEx, (*I)->getLocationContext());
1708bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek        evalLoadCommon(Dst, NodeEx, BoundEx, *I, state, location, tag, LoadTy);
1709b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek      }
1710852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek      return;
1711852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek    }
1712852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  }
1713b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
1714bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek  evalLoadCommon(Dst, NodeEx, BoundEx, Pred, state, location, tag, LoadTy);
1715852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek}
1716852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek
1717bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenekvoid ExprEngine::evalLoadCommon(ExplodedNodeSet &Dst,
1718bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                                const Expr *NodeEx,
1719bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                                const Expr *BoundEx,
1720bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                                ExplodedNode *Pred,
1721bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                                ProgramStateRef state,
1722bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                                SVal location,
1723bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                                const ProgramPointTag *tag,
1724bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                                QualType LoadTy) {
1725bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek  assert(NodeEx);
1726bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek  assert(BoundEx);
17271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Evaluate the location (checks for bad dereferences).
1728b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  ExplodedNodeSet Tmp;
1729bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek  evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location, tag, true);
1730b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  if (Tmp.empty())
17311b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek    return;
1732b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
173366c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(Tmp, Dst, *currBldrCtx);
173473c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis  if (location.isUndef())
173573c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis    return;
1736b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
17371b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek  // Proceed with the load.
1738b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) {
1739db5e8cd095d1ffdd18f5620ad2348b5f386bebe3Anna Zaks    state = (*NI)->getState();
17405eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    const LocationContext *LCtx = (*NI)->getLocationContext();
174196ebad66c451d79c9f57b1edb31efaeeb23b9a01Ted Kremenek
17427affe151f5689b2d3547b8947c4099532c78a021Jordan Rose    SVal V = UnknownVal();
17437affe151f5689b2d3547b8947c4099532c78a021Jordan Rose    if (location.isValid()) {
174496ebad66c451d79c9f57b1edb31efaeeb23b9a01Ted Kremenek      if (LoadTy.isNull())
1745bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek        LoadTy = BoundEx->getType();
17467affe151f5689b2d3547b8947c4099532c78a021Jordan Rose      V = state->getSVal(cast<Loc>(location), LoadTy);
1747b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    }
17487affe151f5689b2d3547b8947c4099532c78a021Jordan Rose
17497affe151f5689b2d3547b8947c4099532c78a021Jordan Rose    Bldr.generateNode(NodeEx, *NI, state->BindExpr(BoundEx, LCtx, V), tag,
17507affe151f5689b2d3547b8947c4099532c78a021Jordan Rose                      ProgramPoint::PostLoadKind);
1751d5b499d43c3526fae7f9ebb6e2d50e79d3496cedZhongxing Xu  }
17521b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek}
17531b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek
1754bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenekvoid ExprEngine::evalLocation(ExplodedNodeSet &Dst,
1755bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              const Stmt *NodeEx,
1756bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              const Stmt *BoundEx,
1757bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              ExplodedNode *Pred,
1758bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              ProgramStateRef state,
1759bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              SVal location,
1760bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              const ProgramPointTag *tag,
1761bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              bool isLoad) {
176266c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder BldrTop(Pred, Dst, *currBldrCtx);
176300b1ad2d56f3e39f95c3f61bf511a531ab6a4fa5Zhongxing Xu  // Early checks for performance reason.
1764769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  if (location.isUnknown()) {
1765b4b817d704287836b52b34369009e682f208aa2bTed Kremenek    return;
1766b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  }
1767b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek
17689c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis  ExplodedNodeSet Src;
1769ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks  BldrTop.takeNodes(Pred);
177066c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(Pred, Src, *currBldrCtx);
1771ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks  if (Pred->getState() != state) {
1772eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis    // Associate this new state with an ExplodedNode.
1773eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis    // FIXME: If I pass null tag, the graph is incorrect, e.g for
1774eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis    //   int *p;
1775eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis    //   p = 0;
1776eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis    //   *p = 0xDEADBEEF;
1777eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis    // "p = 0" is not noted as "Null pointer value stored to 'p'" but
1778eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis    // instead "int *p" is noted as
1779eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis    // "Variable 'p' initialized to a null pointer value"
1780ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek
1781fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    static SimpleProgramPointTag tag("ExprEngine: Location");
1782fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    Bldr.generateNode(NodeEx, Pred, state, &tag);
17830296c22557b3735e2ffeff690eb46fb0e9152bccTed Kremenek  }
1784ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks  ExplodedNodeSet Tmp;
1785bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek  getCheckerManager().runCheckersForLocation(Tmp, Src, location, isLoad,
1786bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                                             NodeEx, BoundEx, *this);
1787ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks  BldrTop.addNodes(Tmp);
1788ec96a2d52d16e150baaf629cd35e3fabff5d8915Ted Kremenek}
1789ec96a2d52d16e150baaf629cd35e3fabff5d8915Ted Kremenek
17906c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenekstd::pair<const ProgramPointTag *, const ProgramPointTag*>
17910caa2d47b84337e942b3f6652adfafe4ae506cfeTed KremenekExprEngine::geteagerlyAssumeBinOpBifurcationTags() {
17926c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek  static SimpleProgramPointTag
17930caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek         eagerlyAssumeBinOpBifurcationTrue("ExprEngine : Eagerly Assume True"),
17940caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek         eagerlyAssumeBinOpBifurcationFalse("ExprEngine : Eagerly Assume False");
17950caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek  return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue,
17960caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek                        &eagerlyAssumeBinOpBifurcationFalse);
17976c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek}
17986c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek
17990caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenekvoid ExprEngine::evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst,
18000caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek                                                   ExplodedNodeSet &Src,
18010caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek                                                   const Expr *Ex) {
180266c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(Src, Dst, *currBldrCtx);
180386b39f20d5091ca3fdcbeb4a22766aaffdf6ac35Ted Kremenek
1804031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) {
1805031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu    ExplodedNode *Pred = *I;
1806b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek    // Test if the previous node was as the same expression.  This can happen
1807b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek    // when the expression fails to evaluate to anything meaningful and
1808b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek    // (as an optimization) we don't generate a node.
18091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ProgramPoint P = Pred->getLocation();
1810b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek    if (!isa<PostStmt>(P) || cast<PostStmt>(P).getStmt() != Ex) {
1811b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek      continue;
18121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
1813b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek
18148bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek    ProgramStateRef state = Pred->getState();
18155eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    SVal V = state->getSVal(Ex, Pred->getLocationContext());
18165344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks    nonloc::SymbolVal *SEV = dyn_cast<nonloc::SymbolVal>(&V);
18175344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks    if (SEV && SEV->isExpression()) {
18186c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek      const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags =
18190caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek        geteagerlyAssumeBinOpBifurcationTags();
18206c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek
18216960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose      ProgramStateRef StateTrue, StateFalse;
18226960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose      tie(StateTrue, StateFalse) = state->assume(*SEV);
18236960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose
182448af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek      // First assume that the condition is true.
18256960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose      if (StateTrue) {
182686b39f20d5091ca3fdcbeb4a22766aaffdf6ac35Ted Kremenek        SVal Val = svalBuilder.makeIntVal(1U, Ex->getType());
18275eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek        StateTrue = StateTrue->BindExpr(Ex, Pred->getLocationContext(), Val);
1828fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose        Bldr.generateNode(Ex, Pred, StateTrue, tags.first);
182948af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek      }
18301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
183148af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek      // Next, assume that the condition is false.
18326960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose      if (StateFalse) {
183386b39f20d5091ca3fdcbeb4a22766aaffdf6ac35Ted Kremenek        SVal Val = svalBuilder.makeIntVal(0U, Ex->getType());
18345eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek        StateFalse = StateFalse->BindExpr(Ex, Pred->getLocationContext(), Val);
1835fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose        Bldr.generateNode(Ex, Pred, StateFalse, tags.second);
183648af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek      }
183748af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek    }
183848af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek  }
183948af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek}
184048af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek
1841df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosiervoid ExprEngine::VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred,
1842df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier                                 ExplodedNodeSet &Dst) {
184366c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
1844a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen  // We have processed both the inputs and the outputs.  All of the outputs
1845a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen  // should evaluate to Locs.  Nuke all of their values.
18461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1847a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen  // FIXME: Some day in the future it would be nice to allow a "plug-in"
1848a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen  // which interprets the inline asm and stores proper results in the
1849a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen  // outputs.
18501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1851a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen  ProgramStateRef state = Pred->getState();
18521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1853df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier  for (GCCAsmStmt::const_outputs_iterator OI = A->begin_outputs(),
1854a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen       OE = A->end_outputs(); OI != OE; ++OI) {
1855a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen    SVal X = state->getSVal(*OI, Pred->getLocationContext());
1856a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen    assert (!isa<NonLoc>(X));  // Should be an Lval, or unknown, undef.
18571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1858a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen    if (isa<Loc>(X))
1859a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen      state = state->bindLoc(cast<Loc>(X), UnknownVal());
1860ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek  }
18611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1862a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen  Bldr.generateNode(A, Pred, state);
1863ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek}
1864ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek
18658cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosiervoid ExprEngine::VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred,
18668cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier                                ExplodedNodeSet &Dst) {
186766c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
18688cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier  Bldr.generateNode(A, Pred, Pred->getState());
18698cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier}
18708cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier
1871094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek//===----------------------------------------------------------------------===//
1872e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek// Visualization.
1873ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek//===----------------------------------------------------------------------===//
1874ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek
1875aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek#ifndef NDEBUG
1876d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisstatic ExprEngine* GraphPrintCheckerState;
1877e97ca065c91ff9ca2a2a42eb443eaa553c40441cTed Kremenekstatic SourceManager* GraphPrintSourceManager;
18783b4f6702860208692f6ef28401e68de4e3ff9af9Ted Kremenek
1879aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremeneknamespace llvm {
1880aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenektemplate<>
188147491f8b7adf9d42a404d44c073e8a5308fa6cfcDouglas Gregorstruct DOTGraphTraits<ExplodedNode*> :
1882aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek  public DefaultDOTGraphTraits {
1883006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser
1884006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser  DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
1885006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser
1886d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  // FIXME: Since we do not cache error nodes in ExprEngine now, this does not
1887ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu  // work.
18889c378f705405d37f49795d5e915989de774fe11fTed Kremenek  static std::string getNodeAttributes(const ExplodedNode *N, void*) {
18891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
189010f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#if 0
189110f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek      // FIXME: Replace with a general scheme to tell if the node is
189210f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek      // an error node.
1893a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek    if (GraphPrintCheckerState->isImplicitNullDeref(N) ||
18949dca062461a6244cf0f733346657fa3eee853f9bTed Kremenek        GraphPrintCheckerState->isExplicitNullDeref(N) ||
18954a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek        GraphPrintCheckerState->isUndefDeref(N) ||
18964a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek        GraphPrintCheckerState->isUndefStore(N) ||
18974a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek        GraphPrintCheckerState->isUndefControlFlow(N) ||
18985e03fcb5420c33207433dd6f800588e256dd9bdbTed Kremenek        GraphPrintCheckerState->isUndefResult(N) ||
18992ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek        GraphPrintCheckerState->isBadCall(N) ||
19002ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek        GraphPrintCheckerState->isUndefArg(N))
1901a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek      return "color=\"red\",style=\"filled\"";
19021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19038cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek    if (GraphPrintCheckerState->isNoReturnCall(N))
19048cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek      return "color=\"blue\",style=\"filled\"";
19052055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu#endif
1906a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek    return "";
1907a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek  }
19081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
190928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose  static void printLocation(llvm::raw_ostream &Out, SourceLocation SLoc) {
191028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose    if (SLoc.isFileID()) {
191128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose      Out << "\\lline="
191228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        << GraphPrintSourceManager->getExpansionLineNumber(SLoc)
191328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        << " col="
191428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        << GraphPrintSourceManager->getExpansionColumnNumber(SLoc)
191528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        << "\\l";
191628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose    }
191728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose  }
191828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose
19199c378f705405d37f49795d5e915989de774fe11fTed Kremenek  static std::string getNodeLabel(const ExplodedNode *N, void*){
19201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
192153ba0b636194dbeaa65a6f85316c9397a0c5298bTed Kremenek    std::string sbuf;
192253ba0b636194dbeaa65a6f85316c9397a0c5298bTed Kremenek    llvm::raw_string_ostream Out(sbuf);
1923803c9edd06e8f936821525d36b1d8cc131e37d44Ted Kremenek
1924803c9edd06e8f936821525d36b1d8cc131e37d44Ted Kremenek    // Program Location.
1925aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek    ProgramPoint Loc = N->getLocation();
19261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1927aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek    switch (Loc.getKind()) {
19280b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      case ProgramPoint::BlockEntranceKind: {
19291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        Out << "Block Entrance: B"
1930aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek            << cast<BlockEntrance>(Loc).getBlock()->getBlockID();
19310b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        if (const NamedDecl *ND =
19320b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                    dyn_cast<NamedDecl>(Loc.getLocationContext()->getDecl())) {
19330b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks          Out << " (";
19340b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks          ND->printName(Out);
19350b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks          Out << ")";
19360b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        }
1937aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek        break;
19380b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      }
19391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1940aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek      case ProgramPoint::BlockExitKind:
1941aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek        assert (false);
1942aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek        break;
19431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1944102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor      case ProgramPoint::CallEnterKind:
1945102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor        Out << "CallEnter";
1946102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor        break;
1947102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
19480b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      case ProgramPoint::CallExitBeginKind:
19490b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        Out << "CallExitBegin";
19500b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        break;
19510b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks
19520b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      case ProgramPoint::CallExitEndKind:
19530b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        Out << "CallExitEnd";
19540b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        break;
19550b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks
19560b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      case ProgramPoint::PostStmtPurgeDeadSymbolsKind:
19570b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        Out << "PostStmtPurgeDeadSymbols";
19580b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        break;
19590b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks
19600b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      case ProgramPoint::PreStmtPurgeDeadSymbolsKind:
19610b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        Out << "PreStmtPurgeDeadSymbols";
1962102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor        break;
1963102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
19645903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks      case ProgramPoint::EpsilonKind:
19655903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks        Out << "Epsilon Point";
19665903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks        break;
19675903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks
196828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose      case ProgramPoint::PreImplicitCallKind: {
196928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        ImplicitCallPoint *PC = cast<ImplicitCallPoint>(&Loc);
197028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        Out << "PreCall: ";
197128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose
197228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        // FIXME: Get proper printing options.
197328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        PC->getDecl()->print(Out, LangOptions());
197428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        printLocation(Out, PC->getLocation());
197528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        break;
197628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose      }
197728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose
197828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose      case ProgramPoint::PostImplicitCallKind: {
197928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        ImplicitCallPoint *PC = cast<ImplicitCallPoint>(&Loc);
198028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        Out << "PostCall: ";
198128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose
198228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        // FIXME: Get proper printing options.
198328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        PC->getDecl()->print(Out, LangOptions());
198428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        printLocation(Out, PC->getLocation());
198528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose        break;
198628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose      }
198728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose
1988aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek      default: {
19895f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek        if (StmtPoint *L = dyn_cast<StmtPoint>(&Loc)) {
19909c378f705405d37f49795d5e915989de774fe11fTed Kremenek          const Stmt *S = L->getStmt();
19918c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
199231ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky          Out << S->getStmtClassName() << ' ' << (const void*) S << ' ';
1993e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner          LangOptions LO; // FIXME.
1994e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner          S->printPretty(Out, 0, PrintingPolicy(LO));
199528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose          printLocation(Out, S->getLocStart());
19961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19975f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek          if (isa<PreStmt>(Loc))
19981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            Out << "\\lPreStmt\\l;";
19995f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek          else if (isa<PostLoad>(Loc))
20007090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek            Out << "\\lPostLoad\\l;";
20017090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek          else if (isa<PostStore>(Loc))
20027090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek            Out << "\\lPostStore\\l";
20037090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek          else if (isa<PostLValue>(Loc))
20047090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek            Out << "\\lPostLValue\\l";
20051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
200610f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#if 0
200710f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek            // FIXME: Replace with a general scheme to determine
200810f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek            // the name of the check.
20098c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek          if (GraphPrintCheckerState->isImplicitNullDeref(N))
20108c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek            Out << "\\|Implicit-Null Dereference.\\l";
20118c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek          else if (GraphPrintCheckerState->isExplicitNullDeref(N))
20128c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek            Out << "\\|Explicit-Null Dereference.\\l";
20138c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek          else if (GraphPrintCheckerState->isUndefDeref(N))
20148c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek            Out << "\\|Dereference of undefialied value.\\l";
20158c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek          else if (GraphPrintCheckerState->isUndefStore(N))
20168c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek            Out << "\\|Store to Undefined Loc.";
20178c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek          else if (GraphPrintCheckerState->isUndefResult(N))
20188c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek            Out << "\\|Result of operation is undefined.";
20198c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek          else if (GraphPrintCheckerState->isNoReturnCall(N))
20208c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek            Out << "\\|Call to function marked \"noreturn\".";
20218c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek          else if (GraphPrintCheckerState->isBadCall(N))
20228c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek            Out << "\\|Call to NULL/Undefined.";
20238c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek          else if (GraphPrintCheckerState->isUndefArg(N))
20248c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek            Out << "\\|Argument in call is undefined";
202510f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#endif
20261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20278c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek          break;
20288c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek        }
20298c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek
20309c378f705405d37f49795d5e915989de774fe11fTed Kremenek        const BlockEdge &E = cast<BlockEdge>(Loc);
2031aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek        Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
2032aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek            << E.getDst()->getBlockID()  << ')';
20331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20349c378f705405d37f49795d5e915989de774fe11fTed Kremenek        if (const Stmt *T = E.getSrc()->getTerminator()) {
20351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2036e97ca065c91ff9ca2a2a42eb443eaa553c40441cTed Kremenek          SourceLocation SLoc = T->getLocStart();
20371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2038b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek          Out << "\\|Terminator: ";
2039e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner          LangOptions LO; // FIXME.
2040e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner          E.getSrc()->printTerminator(Out, LO);
20411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20429b5551d7f0209cec8b9c555cf70e893940674e5cTed Kremenek          if (SLoc.isFileID()) {
20439b5551d7f0209cec8b9c555cf70e893940674e5cTed Kremenek            Out << "\\lline="
2044642116259e8df6286063a17361c20e95b5017a0aChandler Carruth              << GraphPrintSourceManager->getExpansionLineNumber(SLoc)
20457da5aea7669e6db3e593162b8a123aef06a04d07Chris Lattner              << " col="
2046a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruth              << GraphPrintSourceManager->getExpansionColumnNumber(SLoc);
20479b5551d7f0209cec8b9c555cf70e893940674e5cTed Kremenek          }
20481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2049daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek          if (isa<SwitchStmt>(T)) {
20509c378f705405d37f49795d5e915989de774fe11fTed Kremenek            const Stmt *Label = E.getDst()->getLabel();
20511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            if (Label) {
20539c378f705405d37f49795d5e915989de774fe11fTed Kremenek              if (const CaseStmt *C = dyn_cast<CaseStmt>(Label)) {
2054daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek                Out << "\\lcase ";
2055e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner                LangOptions LO; // FIXME.
2056e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner                C->getLHS()->printPretty(Out, 0, PrintingPolicy(LO));
20571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20589c378f705405d37f49795d5e915989de774fe11fTed Kremenek                if (const Stmt *RHS = C->getRHS()) {
2059daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek                  Out << " .. ";
2060e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner                  RHS->printPretty(Out, 0, PrintingPolicy(LO));
2061daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek                }
20621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2063daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek                Out << ":";
2064daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek              }
2065daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek              else {
2066daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek                assert (isa<DefaultStmt>(Label));
2067daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek                Out << "\\ldefault:";
2068daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek              }
2069daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek            }
20701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            else
2071daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek              Out << "\\l(implicit) default:";
2072daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek          }
2073daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek          else if (isa<IndirectGotoStmt>(T)) {
2074b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek            // FIXME
2075b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek          }
2076b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek          else {
2077b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek            Out << "\\lCondition: ";
2078b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek            if (*E.getSrc()->succ_begin() == E.getDst())
2079b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek              Out << "true";
2080b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek            else
20811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump              Out << "false";
2082b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek          }
20831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2084b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek          Out << "\\l";
2085b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek        }
20861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
208710f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#if 0
208810f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek          // FIXME: Replace with a general scheme to determine
208910f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek          // the name of the check.
20904a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek        if (GraphPrintCheckerState->isUndefControlFlow(N)) {
20914a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek          Out << "\\|Control-flow based on\\lUndefined value.\\l";
20923b4f6702860208692f6ef28401e68de4e3ff9af9Ted Kremenek        }
209310f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#endif
2094aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek      }
2095aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek    }
20961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20978bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek    ProgramStateRef state = N->getState();
209831ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky    Out << "\\|StateID: " << (const void*) state.getPtr()
209931ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky        << " NodeID: " << (const void*) N << "\\|";
21005eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    state->printDOT(Out);
2101ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek
2102ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek    Out << "\\l";
2103ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek
2104ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek    if (const ProgramPointTag *tag = Loc.getTag()) {
2105ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek      Out << "\\|Tag: " << tag->getTagDescription();
2106ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek      Out << "\\l";
2107ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek    }
2108aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek    return Out.str();
2109aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek  }
2110aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek};
21111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} // end llvm namespace
2112aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek#endif
2113aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek
2114ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek#ifndef NDEBUG
21157ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenektemplate <typename ITERATOR>
21169c378f705405d37f49795d5e915989de774fe11fTed KremenekExplodedNode *GetGraphNode(ITERATOR I) { return *I; }
21177ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenek
2118031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xutemplate <> ExplodedNode*
2119031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing XuGetGraphNode<llvm::DenseMap<ExplodedNode*, Expr*>::iterator>
2120031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  (llvm::DenseMap<ExplodedNode*, Expr*>::iterator I) {
21217ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenek  return I->first;
21227ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenek}
2123ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek#endif
2124ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek
2125d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ViewGraph(bool trim) {
21261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#ifndef NDEBUG
2127ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek  if (trim) {
2128031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu    std::vector<ExplodedNode*> Src;
2129940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek
2130940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek    // Flush any outstanding reports to make sure we cover all the nodes.
2131940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek    // This does not cause them to get displayed.
2132940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek    for (BugReporter::iterator I=BR.begin(), E=BR.end(); I!=E; ++I)
2133940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek      const_cast<BugType*>(*I)->FlushReports(BR);
2134940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek
2135940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek    // Iterate through the reports and get their nodes.
2136404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    for (BugReporter::EQClasses_iterator
2137404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis           EI = BR.EQClasses_begin(), EE = BR.EQClasses_end(); EI != EE; ++EI) {
21384a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer      ExplodedNode *N = const_cast<ExplodedNode*>(EI->begin()->getErrorNode());
2139404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis      if (N) Src.push_back(N);
2140940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek    }
21411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21427ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenek    ViewGraph(&Src[0], &Src[0]+Src.size());
2143ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek  }
2144493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek  else {
2145493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek    GraphPrintCheckerState = this;
2146493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek    GraphPrintSourceManager = &getContext().getSourceManager();
2147ae6814efb6c41bd0c0f6413d25097105284d5be7Ted Kremenek
2148d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis    llvm::ViewGraph(*G.roots_begin(), "ExprEngine");
21491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2150493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek    GraphPrintCheckerState = NULL;
2151493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek    GraphPrintSourceManager = NULL;
2152493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek  }
2153493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek#endif
2154493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek}
2155493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek
2156d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ViewGraph(ExplodedNode** Beg, ExplodedNode** End) {
2157493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek#ifndef NDEBUG
2158493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek  GraphPrintCheckerState = this;
2159493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek  GraphPrintSourceManager = &getContext().getSourceManager();
21601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2161031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  std::auto_ptr<ExplodedGraph> TrimmedG(G.Trim(Beg, End).first);
2162493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek
2163cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  if (!TrimmedG.get())
21646cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer    llvm::errs() << "warning: Trimmed ExplodedGraph is empty.\n";
2165cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  else
2166d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis    llvm::ViewGraph(*TrimmedG->roots_begin(), "TrimmedExprEngine");
21671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21683b4f6702860208692f6ef28401e68de4e3ff9af9Ted Kremenek  GraphPrintCheckerState = NULL;
2169e97ca065c91ff9ca2a2a42eb443eaa553c40441cTed Kremenek  GraphPrintSourceManager = NULL;
2170e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek#endif
2171ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek}
2172