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