ExprEngineCXX.cpp revision d1e5a89226da79f7e6f43d40facc46abda9e5245
17ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman//===- ExprEngineCXX.cpp - ExprEngine support for C++ -----------*- C++ -*-===//
27ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman//
37ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman//                     The LLVM Compiler Infrastructure
47ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman//
57ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// This file is distributed under the University of Illinois Open Source
67ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// License. See LICENSE.TXT for details.
77ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman//
87ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman//===----------------------------------------------------------------------===//
97ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman//
107ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman//  This file defines the C++ expression evaluation engine.
117ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman//
127ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman//===----------------------------------------------------------------------===//
137ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman
147ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#include "clang/StaticAnalyzer/Core/CheckerManager.h"
157ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
167ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
177ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
187ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#include "clang/AST/DeclCXX.h"
197ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman
207ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmanusing namespace clang;
217ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmanusing namespace ento;
227ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman
237ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmannamespace {
247ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmanclass CallExprWLItem {
257ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmanpublic:
267ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  CallExpr::const_arg_iterator I;
277ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  ExplodedNode *N;
287ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman
297ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  CallExprWLItem(const CallExpr::const_arg_iterator &i, ExplodedNode *n)
307ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman    : I(i), N(n) {}
317ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman};
32b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad}
337ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman
347ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmanvoid ExprEngine::evalArguments(ConstExprIterator AI, ConstExprIterator AE,
357ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman                                 const FunctionProtoType *FnType,
367ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman                                 ExplodedNode *Pred, ExplodedNodeSet &Dst,
37b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad                                 bool FstArgAsLValue) {
387ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman
39190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer
40b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad  SmallVector<CallExprWLItem, 20> WorkList;
41190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer  WorkList.reserve(AE - AI);
42b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad  WorkList.push_back(CallExprWLItem(AI, Pred));
43b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad
44e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  while (!WorkList.empty()) {
45b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad    CallExprWLItem Item = WorkList.back();
46190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer    WorkList.pop_back();
47e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
48190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer    if (Item.I == AE) {
49b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad      Dst.insert(Item.N);
50b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad      continue;
51b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad    }
52190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer
537ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman    // Evaluate the argument.
54b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad    ExplodedNodeSet Tmp;
55b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad    if (FstArgAsLValue) {
56b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad      FstArgAsLValue = false;
57b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad    }
587ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman
59e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    Visit(*Item.I, Item.N, Tmp);
60e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    ++(Item.I);
61e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI != NE; ++NI)
62e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      WorkList.push_back(CallExprWLItem(Item.I, *NI));
63e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  }
64e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer}
65e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
66e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramervoid ExprEngine::evalCallee(const CallExpr *callExpr,
677ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman                            const ExplodedNodeSet &src,
687ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman                            ExplodedNodeSet &dest) {
697ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman
707ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  const Expr *callee = 0;
71190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer
72190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer  switch (callExpr->getStmtClass()) {
7357240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer    case Stmt::CXXMemberCallExprClass: {
74e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      // Evaluate the implicit object argument that is the recipient of the
75e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      // call.
7657240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer      callee = cast<CXXMemberCallExpr>(callExpr)->getImplicitObjectArgument();
77e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
78190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer      // FIXME: handle member pointers.
79190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer      if (!callee)
80190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer        return;
81190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer
82190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer      break;
83190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer    }
84190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer    default: {
85190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer      callee = callExpr->getCallee()->IgnoreParens();
86190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer      break;
87190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer    }
88190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer  }
89190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer
90190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer  for (ExplodedNodeSet::iterator i = src.begin(), e = src.end(); i != e; ++i)
91190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer    Visit(callee, *i, dest);
92190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer}
93190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer
94190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramerconst CXXThisRegion *ExprEngine::getCXXThisRegion(const CXXRecordDecl *D,
95190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer                                                 const StackFrameContext *SFC) {
96190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer  const Type *T = D->getTypeForDecl();
97190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer  QualType PT = getContext().getPointerType(QualType(T, 0));
98190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer  return svalBuilder.getRegionManager().getCXXThisRegion(PT, SFC);
99190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer}
100190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer
101190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramerconst CXXThisRegion *ExprEngine::getCXXThisRegion(const CXXMethodDecl *decl,
102190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer                                            const StackFrameContext *frameCtx) {
103190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer  return svalBuilder.getRegionManager().
104190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer                    getCXXThisRegion(decl->getThisType(getContext()), frameCtx);
105190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer}
106190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer
107190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramervoid ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
108190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer                                          ExplodedNode *Pred,
109190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer                                          ExplodedNodeSet &Dst) {
110e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  ExplodedNodeSet Tmp;
111e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  Visit(ME->GetTemporaryExpr(), Pred, Tmp);
1127ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) {
1137ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman    const ProgramState *state = (*I)->getState();
1147ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman
1157ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman    // Bind the temporary object to the value of the expression. Then bind
11657240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer    // the expression to the location of the object.
11757240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer    SVal V = state->getSVal(ME->GetTemporaryExpr());
11857240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer
11957240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer    const MemRegion *R =
12057240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer      svalBuilder.getRegionManager().getCXXTempObjectRegion(ME,
12157240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer                                                   Pred->getLocationContext());
12257240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer
12357240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer    state = state->bindLoc(loc::MemRegionVal(R), V);
1247ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman    MakeNode(Dst, ME, Pred, state->BindExpr(ME, loc::MemRegionVal(R)));
1257ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  }
1267ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman}
1277ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman
1287ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmanvoid ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E,
1297ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman                                       const MemRegion *Dest,
1307ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman                                       ExplodedNode *Pred,
1317ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman                                       ExplodedNodeSet &destNodes) {
1327ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman
1337ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  const CXXConstructorDecl *CD = E->getConstructor();
1347ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  assert(CD);
1357ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman
1367ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#if 0
1377ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  if (!(CD->doesThisDeclarationHaveABody() && AMgr.shouldInlineCall()))
1387ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman    // FIXME: invalidate the object.
1397ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman    return;
1407ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#endif
1417ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman
1427ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  // Evaluate other arguments.
1437ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  ExplodedNodeSet argsEvaluated;
1447ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  const FunctionProtoType *FnType = CD->getType()->getAs<FunctionProtoType>();
1457ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  evalArguments(E->arg_begin(), E->arg_end(), FnType, Pred, argsEvaluated);
146190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer
1477ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#if 0
1487ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  // Is the constructor elidable?
1497ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  if (E->isElidable()) {
1507ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman    VisitAggExpr(E->getArg(0), destNodes, Pred, Dst);
1517ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman    // FIXME: this is here to force propagation if VisitAggExpr doesn't
1527ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman    if (destNodes.empty())
1537ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman      destNodes.Add(Pred);
1547ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman    return;
1557ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  }
1567ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#endif
1577ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman
1587ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  // Perform the previsit of the constructor.
159e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  ExplodedNodeSet destPreVisit;
160e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  getCheckerManager().runCheckersForPreStmt(destPreVisit, argsEvaluated, E,
161e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                            *this);
162e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
16357240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer  // Evaluate the constructor.  Currently we don't now allow checker-specific
16457240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer  // implementations of specific constructors (as we do with ordinary
16557240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer  // function calls.  We can re-evaluate this in the future.
16657240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer
1677ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#if 0
1687ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  // Inlining currently isn't fully implemented.
1697ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman
1707ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman  if (AMgr.shouldInlineCall()) {
1717ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman    if (!Dest)
1727ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman      Dest =
1737ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman        svalBuilder.getRegionManager().getCXXTempObjectRegion(E,
174e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                                  Pred->getLocationContext());
175e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
176e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    // The callee stack frame context used to create the 'this'
177e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    // parameter region.
178e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    const StackFrameContext *SFC =
179e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      AMgr.getStackFrame(CD, Pred->getLocationContext(),
180e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                         E, Builder->getBlock(), Builder->getIndex());
181e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
182e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    // Create the 'this' region.
183e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    const CXXThisRegion *ThisR =
184e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      getCXXThisRegion(E->getConstructor()->getParent(), SFC);
185b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad
186b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad    CallEnter Loc(E, SFC, Pred->getLocationContext());
187e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
188e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
189e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    for (ExplodedNodeSet::iterator NI = argsEvaluated.begin(),
190b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad                                  NE = argsEvaluated.end(); NI != NE; ++NI) {
191b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad      const ProgramState *state = (*NI)->getState();
192e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      // Setup 'this' region, so that the ctor is evaluated on the object pointed
193e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      // by 'Dest'.
194e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest));
195e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      if (ExplodedNode *N = Builder->generateNode(Loc, state, *NI))
196e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer        destNodes.Add(N);
197e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    }
198b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad  }
199e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer#endif
200e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
201e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  // Default semantics: invalidate all regions passed as arguments.
202e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  ExplodedNodeSet destCall;
203e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
204e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  for (ExplodedNodeSet::iterator
205e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer        i = destPreVisit.begin(), e = destPreVisit.end();
206b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad       i != e; ++i)
207b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad  {
208e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    ExplodedNode *Pred = *i;
209e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    const LocationContext *LC = Pred->getLocationContext();
210e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    const ProgramState *state = Pred->getState();
211b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad
212b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad    state = invalidateArguments(state, CallOrObjCMessage(E, state), LC);
213e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    Builder->MakeNode(destCall, E, Pred, state);
214e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  }
215b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad
216b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad  // Do the post visit.
217e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  getCheckerManager().runCheckersForPostStmt(destNodes, destCall, E, *this);
218b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad}
219e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
220e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramervoid ExprEngine::VisitCXXDestructor(const CXXDestructorDecl *DD,
221e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                      const MemRegion *Dest,
222e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                      const Stmt *S,
223e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                      ExplodedNode *Pred,
224e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                      ExplodedNodeSet &Dst) {
225e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  if (!(DD->doesThisDeclarationHaveABody() && AMgr.shouldInlineCall()))
226e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    return;
227e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  // Create the context for 'this' region.
228e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  const StackFrameContext *SFC = AMgr.getStackFrame(DD,
229e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                                    Pred->getLocationContext(),
230e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                                    S, Builder->getBlock(),
231e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                                    Builder->getIndex());
232e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
233e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  const CXXThisRegion *ThisR = getCXXThisRegion(DD->getParent(), SFC);
234e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
235e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  CallEnter PP(S, SFC, Pred->getLocationContext());
236e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
237e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  const ProgramState *state = Pred->getState();
238e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest));
239e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  ExplodedNode *N = Builder->generateNode(PP, state, Pred);
240e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  if (N)
241e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    Dst.Add(N);
242e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer}
243e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
244e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramervoid ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
245e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                   ExplodedNodeSet &Dst) {
246e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
247e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  unsigned blockCount = Builder->getCurrentBlockCount();
248e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  DefinedOrUnknownSVal symVal =
249e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    svalBuilder.getConjuredSymbolVal(NULL, CNE, CNE->getType(), blockCount);
250e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion();
251e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
252e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  const ElementRegion *EleReg =
253e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
254e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
255e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  if (CNE->isArray()) {
256e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    // FIXME: allocating an array requires simulating the constructors.
257e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    // For now, just return a symbolicated region.
258e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    const ProgramState *state = Pred->getState();
259e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    state = state->BindExpr(CNE, loc::MemRegionVal(EleReg));
260e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    MakeNode(Dst, CNE, Pred, state);
261e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    return;
262e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  }
263e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
264e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  // Evaluate constructor arguments.
265e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  const FunctionProtoType *FnType = NULL;
266e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  const CXXConstructorDecl *CD = CNE->getConstructor();
267e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  if (CD)
268e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    FnType = CD->getType()->getAs<FunctionProtoType>();
269e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  ExplodedNodeSet argsEvaluated;
270e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  evalArguments(CNE->constructor_arg_begin(), CNE->constructor_arg_end(),
271e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                FnType, Pred, argsEvaluated);
272e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
273e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  // Initialize the object region and bind the 'new' expression.
274e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  for (ExplodedNodeSet::iterator I = argsEvaluated.begin(),
275e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                 E = argsEvaluated.end(); I != E; ++I) {
276e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
277e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    const ProgramState *state = (*I)->getState();
278e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
279e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    // Accumulate list of regions that are invalidated.
280e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    // FIXME: Eventually we should unify the logic for constructor
281e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    // processing in one place.
282e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    SmallVector<const MemRegion*, 10> regionsToInvalidate;
283e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    for (CXXNewExpr::const_arg_iterator
284e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer          ai = CNE->constructor_arg_begin(), ae = CNE->constructor_arg_end();
285e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer          ai != ae; ++ai)
286e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    {
287e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      SVal val = state->getSVal(*ai);
288e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      if (const MemRegion *region = val.getAsRegion())
289e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer        regionsToInvalidate.push_back(region);
290e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    }
291e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
292e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    if (ObjTy->isRecordType()) {
293e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      regionsToInvalidate.push_back(EleReg);
294e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      // Invalidate the regions.
295e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      state = state->invalidateRegions(regionsToInvalidate,
296e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                       CNE, blockCount, 0,
297e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                       /* invalidateGlobals = */ true);
298e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
299e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    } else {
300e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      // Invalidate the regions.
301e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      state = state->invalidateRegions(regionsToInvalidate,
302e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                       CNE, blockCount, 0,
303e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                       /* invalidateGlobals = */ true);
304e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
305e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      if (CNE->hasInitializer()) {
306e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer        SVal V = state->getSVal(*CNE->constructor_arg_begin());
307e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer        state = state->bindLoc(loc::MemRegionVal(EleReg), V);
308e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      } else {
309e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer        // Explicitly set to undefined, because currently we retrieve symbolic
310e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer        // value from symbolic region.
311e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer        state = state->bindLoc(loc::MemRegionVal(EleReg), UndefinedVal());
312e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer      }
313e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    }
314e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    state = state->BindExpr(CNE, loc::MemRegionVal(EleReg));
315e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    MakeNode(Dst, CNE, *I, state);
316e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  }
317e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer}
318e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
319e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramervoid ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
320e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                      ExplodedNode *Pred,ExplodedNodeSet &Dst) {
321e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  // Should do more checking.
322e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  ExplodedNodeSet Argevaluated;
323e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  Visit(CDE->getArgument(), Pred, Argevaluated);
324e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  for (ExplodedNodeSet::iterator I = Argevaluated.begin(),
325e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                 E = Argevaluated.end(); I != E; ++I) {
326e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    const ProgramState *state = (*I)->getState();
327e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    MakeNode(Dst, CDE, *I, state);
328e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  }
329e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer}
330e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
331e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramervoid ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
332e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                    ExplodedNodeSet &Dst) {
333e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  // Get the this object region from StoreManager.
334e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  const MemRegion *R =
335e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer    svalBuilder.getRegionManager().getCXXThisRegion(
336e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                  getContext().getCanonicalType(TE->getType()),
337e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer                                               Pred->getLocationContext());
338e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer
339e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  const ProgramState *state = Pred->getState();
340e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  SVal V = state->getSVal(loc::MemRegionVal(R));
341e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer  MakeNode(Dst, TE, Pred, state->BindExpr(TE, V));
342e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer}
343e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer