1294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek//=-- ExprEngineObjC.cpp - ExprEngine support for Objective-C ---*- C++ -*-===//
2294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek//
3294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek//                     The LLVM Compiler Infrastructure
4294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek//
5294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek// This file is distributed under the University of Illinois Open Source
6294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek// License. See LICENSE.TXT for details.
7294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek//
8294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek//===----------------------------------------------------------------------===//
9294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek//
10294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek//  This file defines ExprEngine's support for Objective-C expressions.
11294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek//
12294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek//===----------------------------------------------------------------------===//
13294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
14c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramer#include "clang/AST/StmtObjC.h"
15294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek#include "clang/StaticAnalyzer/Core/CheckerManager.h"
16f540c54701e3eeb34cb619a3a4eb18f1ac70ef2dJordan Rose#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
17294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
18294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
19294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekusing namespace clang;
20294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekusing namespace ento;
21294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
22294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *Ex,
23294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek                                          ExplodedNode *Pred,
24294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek                                          ExplodedNodeSet &Dst) {
258bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef state = Pred->getState();
265eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  const LocationContext *LCtx = Pred->getLocationContext();
275eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  SVal baseVal = state->getSVal(Ex->getBase(), LCtx);
28294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  SVal location = state->getLValue(Ex->getDecl(), baseVal);
29294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
30294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  ExplodedNodeSet dstIvar;
31e606e3d224d3fa8f6d4358ec66858d46754457a0Jordan Rose  StmtNodeBuilder Bldr(Pred, dstIvar, *currBldrCtx);
32e606e3d224d3fa8f6d4358ec66858d46754457a0Jordan Rose  Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, location));
33294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
34294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  // Perform the post-condition check of the ObjCIvarRefExpr and store
35294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  // the created nodes in 'Dst'.
36294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  getCheckerManager().runCheckersForPostStmt(Dst, dstIvar, Ex, *this);
37294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek}
38294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
39294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S,
40294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek                                             ExplodedNode *Pred,
41294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek                                             ExplodedNodeSet &Dst) {
42294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  getCheckerManager().runCheckersForPreStmt(Dst, Pred, S, *this);
43294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek}
44294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
45294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
46294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek                                            ExplodedNode *Pred,
47294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek                                            ExplodedNodeSet &Dst) {
48294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
49294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  // ObjCForCollectionStmts are processed in two places.  This method
50294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  // handles the case where an ObjCForCollectionStmt* occurs as one of the
51294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  // statements within a basic block.  This transfer function does two things:
52294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //
53294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //  (1) binds the next container value to 'element'.  This creates a new
54294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //      node in the ExplodedGraph.
55294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //
56294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //  (2) binds the value 0/1 to the ObjCForCollectionStmt* itself, indicating
57294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //      whether or not the container has any more elements.  This value
58294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //      will be tested in ProcessBranch.  We need to explicitly bind
59294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //      this value because a container can contain nil elements.
60294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //
61294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  // FIXME: Eventually this logic should actually do dispatches to
62294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //   'countByEnumeratingWithState:objects:count:' (NSFastEnumeration).
63294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //   This will require simulating a temporary NSFastEnumerationState, either
64294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //   through an SVal or through the use of MemRegions.  This value can
65294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //   be affixed to the ObjCForCollectionStmt* instead of 0/1; when the loop
66294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //   terminates we reclaim the temporary (it goes out of scope) and we
67294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //   we can test if the SVal is 0 or if the MemRegion is null (depending
68294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //   on what approach we take).
69294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //
70294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //  For now: simulate (1) by assigning either a symbol or nil if the
71294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //    container is empty.  Thus this transfer function will by default
72294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  //    result in state splitting.
73ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks
74294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  const Stmt *elem = S->getElement();
758bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef state = Pred->getState();
76294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  SVal elementV;
77294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
78294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  if (const DeclStmt *DS = dyn_cast<DeclStmt>(elem)) {
79294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek    const VarDecl *elemD = cast<VarDecl>(DS->getSingleDecl());
806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(elemD->getInit() == nullptr);
81294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek    elementV = state->getLValue(elemD, Pred->getLocationContext());
82294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  }
83294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  else {
845eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    elementV = state->getSVal(elem, Pred->getLocationContext());
85294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  }
86294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
87294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  ExplodedNodeSet dstLocation;
886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  evalLocation(dstLocation, S, elem, Pred, state, elementV, nullptr, false);
891895a0a6936001374f66adbdfcf8abe5edf912eaJordan Rose
901895a0a6936001374f66adbdfcf8abe5edf912eaJordan Rose  ExplodedNodeSet Tmp;
9166c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
921895a0a6936001374f66adbdfcf8abe5edf912eaJordan Rose
93294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  for (ExplodedNodeSet::iterator NI = dstLocation.begin(),
94294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek       NE = dstLocation.end(); NI!=NE; ++NI) {
95294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek    Pred = *NI;
968bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek    ProgramStateRef state = Pred->getState();
975eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    const LocationContext *LCtx = Pred->getLocationContext();
98294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
99294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek    // Handle the case where the container still has elements.
100294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek    SVal TrueV = svalBuilder.makeTruthVal(1);
1018bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek    ProgramStateRef hasElems = state->BindExpr(S, LCtx, TrueV);
102294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
103294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek    // Handle the case where the container has no elements.
104294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek    SVal FalseV = svalBuilder.makeTruthVal(0);
1058bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek    ProgramStateRef noElems = state->BindExpr(S, LCtx, FalseV);
1065251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie
107dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie    if (Optional<loc::MemRegionVal> MV = elementV.getAs<loc::MemRegionVal>())
108294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek      if (const TypedValueRegion *R =
109294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek          dyn_cast<TypedValueRegion>(MV->getRegion())) {
110294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek        // FIXME: The proper thing to do is to really iterate over the
111294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek        //  container.  We will do this with dispatch logic to the store.
112294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek        //  For now, just 'conjure' up a symbolic value.
113294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek        QualType T = R->getValueType();
114294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek        assert(Loc::isLocType(T));
11566c486f275531df6362b3511fc3af6563561801bTed Kremenek        SymbolRef Sym = SymMgr.conjureSymbol(elem, LCtx, T,
11666c486f275531df6362b3511fc3af6563561801bTed Kremenek                                             currBldrCtx->blockCount());
117294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek        SVal V = svalBuilder.makeLoc(Sym);
118294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek        hasElems = hasElems->bindLoc(elementV, V);
119294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
120294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek        // Bind the location to 'nil' on the false branch.
121294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek        SVal nilV = svalBuilder.makeIntVal(0, T);
122294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek        noElems = noElems->bindLoc(elementV, nilV);
123294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek      }
124294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
125294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek    // Create the new nodes.
126ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks    Bldr.generateNode(S, Pred, hasElems);
127ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks    Bldr.generateNode(S, Pred, noElems);
128294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  }
1291895a0a6936001374f66adbdfcf8abe5edf912eaJordan Rose
1301895a0a6936001374f66adbdfcf8abe5edf912eaJordan Rose  // Finally, run any custom checkers.
1311895a0a6936001374f66adbdfcf8abe5edf912eaJordan Rose  // FIXME: Eventually all pre- and post-checks should live in VisitStmt.
1321895a0a6936001374f66adbdfcf8abe5edf912eaJordan Rose  getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
133294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek}
134294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
135d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rosevoid ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME,
136294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek                                  ExplodedNode *Pred,
137294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek                                  ExplodedNodeSet &Dst) {
138d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose  CallEventManager &CEMgr = getStateManager().getCallEventManager();
139d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose  CallEventRef<ObjCMethodCall> Msg =
140d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose    CEMgr.getObjCMethodCall(ME, Pred->getState(), Pred->getLocationContext());
141d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose
142294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  // Handle the previsits checks.
143294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  ExplodedNodeSet dstPrevisit;
14496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  getCheckerManager().runCheckersForPreObjCMessage(dstPrevisit, Pred,
145d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose                                                   *Msg, *this);
14696479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  ExplodedNodeSet dstGenericPrevisit;
14796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  getCheckerManager().runCheckersForPreCall(dstGenericPrevisit, dstPrevisit,
148d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose                                            *Msg, *this);
14996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
150294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  // Proceed with evaluate the message expression.
151294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  ExplodedNodeSet dstEval;
15266c486f275531df6362b3511fc3af6563561801bTed Kremenek  StmtNodeBuilder Bldr(dstGenericPrevisit, dstEval, *currBldrCtx);
153ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks
15496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  for (ExplodedNodeSet::iterator DI = dstGenericPrevisit.begin(),
15596479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose       DE = dstGenericPrevisit.end(); DI != DE; ++DI) {
156294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek    ExplodedNode *Pred = *DI;
157d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose    ProgramStateRef State = Pred->getState();
158d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose    CallEventRef<ObjCMethodCall> UpdatedMsg = Msg.cloneWithState(State);
159294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
160d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose    if (UpdatedMsg->isInstanceMessage()) {
161d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose      SVal recVal = UpdatedMsg->getReceiverSVal();
162294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek      if (!recVal.isUndef()) {
163294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek        // Bifurcate the state into nil and non-nil ones.
1645251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie        DefinedOrUnknownSVal receiverVal =
1655251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie            recVal.castAs<DefinedOrUnknownSVal>();
1665251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie
1678bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek        ProgramStateRef notNilState, nilState;
168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        std::tie(notNilState, nilState) = State->assume(receiverVal);
169294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
170294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek        // There are three cases: can be nil or non-nil, must be nil, must be
171294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek        // non-nil. We ignore must be nil, and merge the rest two into non-nil.
172cde8cdbd6a662c636164465ad309b5f17ff01064Jordan Rose        // FIXME: This ignores many potential bugs (<rdar://problem/11733396>).
173cde8cdbd6a662c636164465ad309b5f17ff01064Jordan Rose        // Revisit once we have lazier constraints.
174294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek        if (nilState && !notNilState) {
175294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek          continue;
176294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek        }
177294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
178294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek        // Check if the "raise" message was sent.
179294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek        assert(notNilState);
1804ef19205b6912316296db74a9073ad6fa60e4ccaTed Kremenek        if (ObjCNoRet.isImplicitNoReturn(ME)) {
181e81ce256b62717dd846bd19aecc4115a0dcd4995Anna Zaks          // If we raise an exception, for now treat it as a sink.
182e81ce256b62717dd846bd19aecc4115a0dcd4995Anna Zaks          // Eventually we will want to handle exceptions properly.
1839428723d6730f4fd257e15b78d24991ae95bbd84Jordan Rose          Bldr.generateSink(ME, Pred, State);
184e81ce256b62717dd846bd19aecc4115a0dcd4995Anna Zaks          continue;
185e81ce256b62717dd846bd19aecc4115a0dcd4995Anna Zaks        }
186294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
187e81ce256b62717dd846bd19aecc4115a0dcd4995Anna Zaks        // Generate a transition to non-Nil state.
18882f2ad456a82da1b9cb7ddfc994c8f5fa44b59e6Jordan Rose        if (notNilState != State) {
1899428723d6730f4fd257e15b78d24991ae95bbd84Jordan Rose          Pred = Bldr.generateNode(ME, Pred, notNilState);
19082f2ad456a82da1b9cb7ddfc994c8f5fa44b59e6Jordan Rose          assert(Pred && "Should have cached out already!");
19182f2ad456a82da1b9cb7ddfc994c8f5fa44b59e6Jordan Rose        }
192294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek      }
193cde8cdbd6a662c636164465ad309b5f17ff01064Jordan Rose    } else {
1944ef19205b6912316296db74a9073ad6fa60e4ccaTed Kremenek      // Check for special class methods that are known to not return
1954ef19205b6912316296db74a9073ad6fa60e4ccaTed Kremenek      // and that we should treat as a sink.
1964ef19205b6912316296db74a9073ad6fa60e4ccaTed Kremenek      if (ObjCNoRet.isImplicitNoReturn(ME)) {
1974ef19205b6912316296db74a9073ad6fa60e4ccaTed Kremenek        // If we raise an exception, for now treat it as a sink.
1984ef19205b6912316296db74a9073ad6fa60e4ccaTed Kremenek        // Eventually we will want to handle exceptions properly.
1999428723d6730f4fd257e15b78d24991ae95bbd84Jordan Rose        Bldr.generateSink(ME, Pred, Pred->getState());
2004ef19205b6912316296db74a9073ad6fa60e4ccaTed Kremenek        continue;
201294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek      }
202294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek    }
2039dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks
20482f2ad456a82da1b9cb7ddfc994c8f5fa44b59e6Jordan Rose    defaultEvalCall(Bldr, Pred, *UpdatedMsg);
205294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  }
206294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
20796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  ExplodedNodeSet dstPostvisit;
208d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose  getCheckerManager().runCheckersForPostCall(dstPostvisit, dstEval,
209d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose                                             *Msg, *this);
21096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
211294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  // Finally, perform the post-condition check of the ObjCMessageExpr and store
212294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  // the created nodes in 'Dst'.
21396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  getCheckerManager().runCheckersForPostObjCMessage(Dst, dstPostvisit,
214d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose                                                    *Msg, *this);
215294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek}
216