ExprEngineCXX.cpp revision 9b663716449b618ba0390b1dbebc54fa8e971124
1cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu//===- GRCXXExprEngine.cpp - C++ expr evaluation engine ---------*- C++ -*-===//
2cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu//
3cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu//                     The LLVM Compiler Infrastructure
4cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu//
5cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu// This file is distributed under the University of Illinois Open Source
6cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu// License. See LICENSE.TXT for details.
7cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu//
8cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu//===----------------------------------------------------------------------===//
9cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu//
10cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu//  This file defines the C++ expression evaluation engine.
11cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu//
12cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu//===----------------------------------------------------------------------===//
13cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
149b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
159b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
16cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu#include "clang/AST/DeclCXX.h"
17cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
18cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xuusing namespace clang;
199ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento;
20cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
21c69c43845aa3ede95af837b8be52868eca55d64dTed Kremeneknamespace {
22c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenekclass CallExprWLItem {
23c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenekpublic:
24c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek  CallExpr::const_arg_iterator I;
25c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek  ExplodedNode *N;
26c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek
27c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek  CallExprWLItem(const CallExpr::const_arg_iterator &i, ExplodedNode *n)
28c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek    : I(i), N(n) {}
29c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek};
30c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek}
31c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek
32d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::evalArguments(ConstExprIterator AI, ConstExprIterator AE,
33b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu                                 const FunctionProtoType *FnType,
3482c63bfa0c5130e0cf274c1974b6157ebefc04feMarcin Swiderski                                 ExplodedNode *Pred, ExplodedNodeSet &Dst,
3582c63bfa0c5130e0cf274c1974b6157ebefc04feMarcin Swiderski                                 bool FstArgAsLValue) {
36c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek
37c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek
38b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu  llvm::SmallVector<CallExprWLItem, 20> WorkList;
39b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu  WorkList.reserve(AE - AI);
40b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu  WorkList.push_back(CallExprWLItem(AI, Pred));
41b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu
42b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu  while (!WorkList.empty()) {
43b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu    CallExprWLItem Item = WorkList.back();
44b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu    WorkList.pop_back();
45b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu
46b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu    if (Item.I == AE) {
47b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu      Dst.insert(Item.N);
48b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu      continue;
49b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu    }
50b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu
51c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek    // Evaluate the argument.
52b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu    ExplodedNodeSet Tmp;
5382c63bfa0c5130e0cf274c1974b6157ebefc04feMarcin Swiderski    if (FstArgAsLValue) {
5482c63bfa0c5130e0cf274c1974b6157ebefc04feMarcin Swiderski      FstArgAsLValue = false;
5582c63bfa0c5130e0cf274c1974b6157ebefc04feMarcin Swiderski    }
56c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek
57892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    Visit(*Item.I, Item.N, Tmp);
58b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu    ++(Item.I);
59b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu    for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI != NE; ++NI)
60b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu      WorkList.push_back(CallExprWLItem(Item.I, *NI));
61b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu  }
62b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu}
63b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu
64d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisconst CXXThisRegion *ExprEngine::getCXXThisRegion(const CXXRecordDecl *D,
65cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu                                                 const StackFrameContext *SFC) {
66f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  const Type *T = D->getTypeForDecl();
67b168cbfa1ca9b50115f8dd787d11d272fff2ad81John McCall  QualType PT = getContext().getPointerType(QualType(T, 0));
68c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  return svalBuilder.getRegionManager().getCXXThisRegion(PT, SFC);
69cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu}
70cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
71d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisconst CXXThisRegion *ExprEngine::getCXXThisRegion(const CXXMethodDecl *decl,
7232303020d0f1a21cbcab65ae0c69a4218dc8f0fbZhongxing Xu                                            const StackFrameContext *frameCtx) {
73c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  return svalBuilder.getRegionManager().
7432303020d0f1a21cbcab65ae0c69a4218dc8f0fbZhongxing Xu                    getCXXThisRegion(decl->getThisType(getContext()), frameCtx);
7532303020d0f1a21cbcab65ae0c69a4218dc8f0fbZhongxing Xu}
7632303020d0f1a21cbcab65ae0c69a4218dc8f0fbZhongxing Xu
77d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::CreateCXXTemporaryObject(const Expr *Ex, ExplodedNode *Pred,
78cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu                                            ExplodedNodeSet &Dst) {
79cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  ExplodedNodeSet Tmp;
80cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  Visit(Ex, Pred, Tmp);
81cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) {
82cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    const GRState *state = GetState(*I);
83cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
84cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    // Bind the temporary object to the value of the expression. Then bind
85cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    // the expression to the location of the object.
86cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    SVal V = state->getSVal(Ex);
87cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
88cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    const MemRegion *R =
89c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek      svalBuilder.getRegionManager().getCXXTempObjectRegion(Ex,
90cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu                                                   Pred->getLocationContext());
91cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
92cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    state = state->bindLoc(loc::MemRegionVal(R), V);
93cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, loc::MemRegionVal(R)));
94cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  }
95cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu}
96cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
97d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E,
987ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu                                         const MemRegion *Dest,
99cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu                                         ExplodedNode *Pred,
100892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                                         ExplodedNodeSet &Dst) {
1017ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu  if (!Dest)
102c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    Dest = svalBuilder.getRegionManager().getCXXTempObjectRegion(E,
1037ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu                                                    Pred->getLocationContext());
1047ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu
105cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  if (E->isElidable()) {
106cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    VisitAggExpr(E->getArg(0), Dest, Pred, Dst);
107cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    return;
108cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  }
109cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
110cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  const CXXConstructorDecl *CD = E->getConstructor();
111cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  assert(CD);
112cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
1137b99d12b4ca67fccdf5090761ba257732e954e75Zhongxing Xu  if (!(CD->isThisDeclarationADefinition() && AMgr.shouldInlineCall()))
114cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    // FIXME: invalidate the object.
115cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    return;
116cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
117cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
118cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  // Evaluate other arguments.
1199c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  ExplodedNodeSet argsEvaluated;
120107ccd1f56836ae57c1a5a9c13c881b0293d1e98Zhongxing Xu  const FunctionProtoType *FnType = CD->getType()->getAs<FunctionProtoType>();
1219c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  evalArguments(E->arg_begin(), E->arg_end(), FnType, Pred, argsEvaluated);
122cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  // The callee stack frame context used to create the 'this' parameter region.
123cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  const StackFrameContext *SFC = AMgr.getStackFrame(CD,
124cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu                                                    Pred->getLocationContext(),
125892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                                                    E, Builder->getBlock(),
126892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                                                    Builder->getIndex());
127cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
1289dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu  const CXXThisRegion *ThisR =getCXXThisRegion(E->getConstructor()->getParent(),
1299dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu                                               SFC);
130cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
13119b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu  CallEnter Loc(E, SFC, Pred->getLocationContext());
1329c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  for (ExplodedNodeSet::iterator NI = argsEvaluated.begin(),
1339c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek                                 NE = argsEvaluated.end(); NI != NE; ++NI) {
134cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    const GRState *state = GetState(*NI);
1353bf185b7e607ea5081c43ba315a9f0161f4aa6c6Zhongxing Xu    // Setup 'this' region, so that the ctor is evaluated on the object pointed
1363bf185b7e607ea5081c43ba315a9f0161f4aa6c6Zhongxing Xu    // by 'Dest'.
1377ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu    state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest));
138cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    ExplodedNode *N = Builder->generateNode(Loc, state, Pred);
139cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    if (N)
140cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu      Dst.Add(N);
141cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  }
142cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu}
143cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
144d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXDestructor(const CXXDestructorDecl *DD,
145b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu                                      const MemRegion *Dest,
146b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu                                      const Stmt *S,
147b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu                                      ExplodedNode *Pred,
148b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu                                      ExplodedNodeSet &Dst) {
149b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu  if (!(DD->isThisDeclarationADefinition() && AMgr.shouldInlineCall()))
150b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu    return;
151b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu  // Create the context for 'this' region.
152b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu  const StackFrameContext *SFC = AMgr.getStackFrame(DD,
153b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu                                                    Pred->getLocationContext(),
154892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                                                    S, Builder->getBlock(),
155b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu                                                    Builder->getIndex());
156b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu
157b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu  const CXXThisRegion *ThisR = getCXXThisRegion(DD->getParent(), SFC);
158b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu
15919b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu  CallEnter PP(S, SFC, Pred->getLocationContext());
160b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu
161b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu  const GRState *state = Pred->getState();
162b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu  state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest));
163b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu  ExplodedNode *N = Builder->generateNode(PP, state, Pred);
164b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu  if (N)
165b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu    Dst.Add(N);
166b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu}
167b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu
168d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE,
169cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu                                          ExplodedNode *Pred,
170cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu                                          ExplodedNodeSet &Dst) {
171cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  // Get the method type.
172cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  const FunctionProtoType *FnType =
173cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu                       MCE->getCallee()->getType()->getAs<FunctionProtoType>();
174cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  assert(FnType && "Method type not available");
175cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
176cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  // Evaluate explicit arguments with a worklist.
1779c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  ExplodedNodeSet argsEvaluated;
1789c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  evalArguments(MCE->arg_begin(), MCE->arg_end(), FnType, Pred, argsEvaluated);
179107ccd1f56836ae57c1a5a9c13c881b0293d1e98Zhongxing Xu
180cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  // Evaluate the implicit object argument.
1819c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  ExplodedNodeSet AllargsEvaluated;
182cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  const MemberExpr *ME = dyn_cast<MemberExpr>(MCE->getCallee()->IgnoreParens());
183cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  if (!ME)
184cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    return;
185cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  Expr *ObjArgExpr = ME->getBase();
1869c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  for (ExplodedNodeSet::iterator I = argsEvaluated.begin(),
1879c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek                                 E = argsEvaluated.end(); I != E; ++I) {
1889c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek      Visit(ObjArgExpr, *I, AllargsEvaluated);
189cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  }
190cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
191a54e824d2322dfd785c2716d0472a8aace2f61b8Ted Kremenek  // Now evaluate the call itself.
192cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
193cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  assert(MD && "not a CXXMethodDecl?");
1949c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  evalMethodCall(MCE, MD, ObjArgExpr, Pred, AllargsEvaluated, Dst);
1956a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski}
1966a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski
197d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *C,
1986a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski                                            ExplodedNode *Pred,
1996a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski                                            ExplodedNodeSet &Dst) {
2006a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski  const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(C->getCalleeDecl());
2016a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski  if (!MD) {
2026a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski    // If the operator doesn't represent a method call treat as regural call.
203892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    VisitCall(C, Pred, C->arg_begin(), C->arg_end(), Dst);
2046a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski    return;
2056a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski  }
2066a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski
2076a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski  // Determine the type of function we're calling (if available).
2086a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski  const FunctionProtoType *Proto = NULL;
2096a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski  QualType FnType = C->getCallee()->IgnoreParens()->getType();
2106a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski  if (const PointerType *FnTypePtr = FnType->getAs<PointerType>())
2116a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski    Proto = FnTypePtr->getPointeeType()->getAs<FunctionProtoType>();
2126a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski
2136a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski  // Evaluate arguments treating the first one (object method is called on)
2146a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski  // as alvalue.
2159c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  ExplodedNodeSet argsEvaluated;
2169c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  evalArguments(C->arg_begin(), C->arg_end(), Proto, Pred, argsEvaluated, true);
2176a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski
2186a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski  // Now evaluate the call itself.
2199c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  evalMethodCall(C, MD, C->getArg(0), Pred, argsEvaluated, Dst);
2206a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski}
2216a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski
222d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::evalMethodCall(const CallExpr *MCE, const CXXMethodDecl *MD,
2236a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski                                  const Expr *ThisExpr, ExplodedNode *Pred,
2246a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski                                  ExplodedNodeSet &Src, ExplodedNodeSet &Dst) {
2256a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski  // Allow checkers to pre-visit the member call.
2266a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski  ExplodedNodeSet PreVisitChecks;
2276a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski  CheckerVisit(MCE, PreVisitChecks, Src, PreVisitStmtCallback);
228cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
229a54e824d2322dfd785c2716d0472a8aace2f61b8Ted Kremenek  if (!(MD->isThisDeclarationADefinition() && AMgr.shouldInlineCall())) {
230cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    // FIXME: conservative method call evaluation.
231a54e824d2322dfd785c2716d0472a8aace2f61b8Ted Kremenek    CheckerVisit(MCE, Dst, PreVisitChecks, PostVisitStmtCallback);
232cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    return;
233a54e824d2322dfd785c2716d0472a8aace2f61b8Ted Kremenek  }
234cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
235cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  const StackFrameContext *SFC = AMgr.getStackFrame(MD,
236cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu                                                    Pred->getLocationContext(),
237892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                                                    MCE,
238cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu                                                    Builder->getBlock(),
239cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu                                                    Builder->getIndex());
24032303020d0f1a21cbcab65ae0c69a4218dc8f0fbZhongxing Xu  const CXXThisRegion *ThisR = getCXXThisRegion(MD, SFC);
24119b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu  CallEnter Loc(MCE, SFC, Pred->getLocationContext());
242a54e824d2322dfd785c2716d0472a8aace2f61b8Ted Kremenek  for (ExplodedNodeSet::iterator I = PreVisitChecks.begin(),
243a54e824d2322dfd785c2716d0472a8aace2f61b8Ted Kremenek         E = PreVisitChecks.end(); I != E; ++I) {
244cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    // Set up 'this' region.
245cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    const GRState *state = GetState(*I);
2466a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski    state = state->bindLoc(loc::MemRegionVal(ThisR), state->getSVal(ThisExpr));
2476a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski    Dst.Add(Builder->generateNode(Loc, state, *I));
248cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  }
249cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu}
250cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
251d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
252cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu                                   ExplodedNodeSet &Dst) {
253cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  if (CNE->isArray()) {
254cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    // FIXME: allocating an array has not been handled.
255cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu    return;
256cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  }
257cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
258cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  unsigned Count = Builder->getCurrentBlockCount();
259c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  DefinedOrUnknownSVal symVal =
260c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    svalBuilder.getConjuredSymbolVal(NULL, CNE, CNE->getType(), Count);
261c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion();
262cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
263cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
264cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
265cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  const ElementRegion *EleReg =
266cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu                         getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
267cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
268b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu  // Evaluate constructor arguments.
269b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu  const FunctionProtoType *FnType = NULL;
270b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu  const CXXConstructorDecl *CD = CNE->getConstructor();
271b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu  if (CD)
272b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu    FnType = CD->getType()->getAs<FunctionProtoType>();
2739c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  ExplodedNodeSet argsEvaluated;
2749c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  evalArguments(CNE->constructor_arg_begin(), CNE->constructor_arg_end(),
2759c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek                FnType, Pred, argsEvaluated);
276cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
277b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu  // Initialize the object region and bind the 'new' expression.
2789c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  for (ExplodedNodeSet::iterator I = argsEvaluated.begin(),
2799c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek                                 E = argsEvaluated.end(); I != E; ++I) {
280b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu    const GRState *state = GetState(*I);
281b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu
282b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu    if (ObjTy->isRecordType()) {
283ff59efd65bb1f2f8d005079597f814a3c8381f95Jordy Rose      state = state->InvalidateRegion(EleReg, CNE, Count);
284b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu    } else {
285b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu      if (CNE->hasInitializer()) {
286b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu        SVal V = state->getSVal(*CNE->constructor_arg_begin());
287b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu        state = state->bindLoc(loc::MemRegionVal(EleReg), V);
288b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu      } else {
289b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu        // Explicitly set to undefined, because currently we retrieve symbolic
290b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu        // value from symbolic region.
291b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu        state = state->bindLoc(loc::MemRegionVal(EleReg), UndefinedVal());
292b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu      }
293b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu    }
294b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu    state = state->BindExpr(CNE, loc::MemRegionVal(EleReg));
295978b935b069e9379e554a2126a525e7b9f458f62Zhongxing Xu    MakeNode(Dst, CNE, *I, state);
296b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu  }
297cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu}
298cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
299d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
30003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu                                      ExplodedNode *Pred,ExplodedNodeSet &Dst) {
3016b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu  // Should do more checking.
3029c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  ExplodedNodeSet Argevaluated;
3039c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  Visit(CDE->getArgument(), Pred, Argevaluated);
3049c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  for (ExplodedNodeSet::iterator I = Argevaluated.begin(),
3059c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek                                 E = Argevaluated.end(); I != E; ++I) {
3066b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu    const GRState *state = GetState(*I);
3076b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu    MakeNode(Dst, CDE, *I, state);
3086b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu  }
3096b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu}
310cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
311d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
3126b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu                                    ExplodedNodeSet &Dst) {
313cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  // Get the this object region from StoreManager.
314cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  const MemRegion *R =
315c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    svalBuilder.getRegionManager().getCXXThisRegion(
316cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu                                  getContext().getCanonicalType(TE->getType()),
317cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu                                               Pred->getLocationContext());
318cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu
319cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  const GRState *state = GetState(Pred);
320cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  SVal V = state->getSVal(loc::MemRegionVal(R));
321cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu  MakeNode(Dst, TE, Pred, state->BindExpr(TE, V));
322cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu}
323