ExprEngineCXX.cpp revision 337e4dbc6859589b8878146a88bebf754e916702
15f7643150411b16e71bc012c6ceb2d865c0a34d4Ted Kremenek//===- ExprEngineCXX.cpp - ExprEngine support for C++ -----------*- 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 14eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerManager.h" 159b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 169b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 17d1e5a89226da79f7e6f43d40facc46abda9e5245Jordy Rose#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h" 18cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu#include "clang/AST/DeclCXX.h" 19337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek#include "clang/AST/StmtCXX.h" 20cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 21cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xuusing namespace clang; 229ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento; 23cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 24c69c43845aa3ede95af837b8be52868eca55d64dTed Kremeneknamespace { 25c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenekclass CallExprWLItem { 26c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenekpublic: 27c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek CallExpr::const_arg_iterator I; 28c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek ExplodedNode *N; 29c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek 30c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek CallExprWLItem(const CallExpr::const_arg_iterator &i, ExplodedNode *n) 31c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek : I(i), N(n) {} 32c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek}; 33c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek} 34c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek 35d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::evalArguments(ConstExprIterator AI, ConstExprIterator AE, 36b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu const FunctionProtoType *FnType, 3782c63bfa0c5130e0cf274c1974b6157ebefc04feMarcin Swiderski ExplodedNode *Pred, ExplodedNodeSet &Dst, 3882c63bfa0c5130e0cf274c1974b6157ebefc04feMarcin Swiderski bool FstArgAsLValue) { 39c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek 40c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek 415f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CallExprWLItem, 20> WorkList; 42b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu WorkList.reserve(AE - AI); 43b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu WorkList.push_back(CallExprWLItem(AI, Pred)); 44b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu 45b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu while (!WorkList.empty()) { 46b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu CallExprWLItem Item = WorkList.back(); 47b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu WorkList.pop_back(); 48b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu 49b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu if (Item.I == AE) { 50b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu Dst.insert(Item.N); 51b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu continue; 52b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu } 53b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu 54c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek // Evaluate the argument. 55b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu ExplodedNodeSet Tmp; 5682c63bfa0c5130e0cf274c1974b6157ebefc04feMarcin Swiderski if (FstArgAsLValue) { 5782c63bfa0c5130e0cf274c1974b6157ebefc04feMarcin Swiderski FstArgAsLValue = false; 5882c63bfa0c5130e0cf274c1974b6157ebefc04feMarcin Swiderski } 59c69c43845aa3ede95af837b8be52868eca55d64dTed Kremenek 60892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek Visit(*Item.I, Item.N, Tmp); 61b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu ++(Item.I); 62b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI != NE; ++NI) 63b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu WorkList.push_back(CallExprWLItem(Item.I, *NI)); 64b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu } 65b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu} 66b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu 67b277159055933e610bbc80262b600d3ad7e0595cTed Kremenekvoid ExprEngine::evalCallee(const CallExpr *callExpr, 68b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek const ExplodedNodeSet &src, 69b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek ExplodedNodeSet &dest) { 70b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek 71b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek const Expr *callee = 0; 72b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek 73b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek switch (callExpr->getStmtClass()) { 74b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek case Stmt::CXXMemberCallExprClass: { 75b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek // Evaluate the implicit object argument that is the recipient of the 76b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek // call. 77b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek callee = cast<CXXMemberCallExpr>(callExpr)->getImplicitObjectArgument(); 78b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek 79b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek // FIXME: handle member pointers. 80b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek if (!callee) 81b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek return; 82b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek 83b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek break; 84b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek } 85b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek default: { 86b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek callee = callExpr->getCallee()->IgnoreParens(); 87b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek break; 88b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek } 89b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek } 90b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek 91b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek for (ExplodedNodeSet::iterator i = src.begin(), e = src.end(); i != e; ++i) 92b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek Visit(callee, *i, dest); 93b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek} 94b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek 95d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisconst CXXThisRegion *ExprEngine::getCXXThisRegion(const CXXRecordDecl *D, 96cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu const StackFrameContext *SFC) { 97f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall const Type *T = D->getTypeForDecl(); 98b168cbfa1ca9b50115f8dd787d11d272fff2ad81John McCall QualType PT = getContext().getPointerType(QualType(T, 0)); 99c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek return svalBuilder.getRegionManager().getCXXThisRegion(PT, SFC); 100cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu} 101cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 102d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisconst CXXThisRegion *ExprEngine::getCXXThisRegion(const CXXMethodDecl *decl, 10332303020d0f1a21cbcab65ae0c69a4218dc8f0fbZhongxing Xu const StackFrameContext *frameCtx) { 104c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek return svalBuilder.getRegionManager(). 10532303020d0f1a21cbcab65ae0c69a4218dc8f0fbZhongxing Xu getCXXThisRegion(decl->getThisType(getContext()), frameCtx); 10632303020d0f1a21cbcab65ae0c69a4218dc8f0fbZhongxing Xu} 10732303020d0f1a21cbcab65ae0c69a4218dc8f0fbZhongxing Xu 108eea72a925f294225391ecec876a342771c09b635Ted Kremenekvoid ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, 109eea72a925f294225391ecec876a342771c09b635Ted Kremenek ExplodedNode *Pred, 110eea72a925f294225391ecec876a342771c09b635Ted Kremenek ExplodedNodeSet &Dst) { 111aa0aeb1cbe117db68d35700cb3a34aace0f99b99Anna Zaks StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 1126a835dddf45922e71a87637fdfac0863de65123cTed Kremenek const Expr *tempExpr = ME->GetTemporaryExpr()->IgnoreParens(); 1138bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 1145eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 115cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 1166a835dddf45922e71a87637fdfac0863de65123cTed Kremenek // Bind the temporary object to the value of the expression. Then bind 1176a835dddf45922e71a87637fdfac0863de65123cTed Kremenek // the expression to the location of the object. 1185eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal V = state->getSVal(tempExpr, Pred->getLocationContext()); 119cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 1206a835dddf45922e71a87637fdfac0863de65123cTed Kremenek const MemRegion *R = 1215eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek svalBuilder.getRegionManager().getCXXTempObjectRegion(ME, LCtx); 122cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 1236a835dddf45922e71a87637fdfac0863de65123cTed Kremenek state = state->bindLoc(loc::MemRegionVal(R), V); 1245eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Bldr.generateNode(ME, Pred, state->BindExpr(ME, LCtx, loc::MemRegionVal(R))); 125cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu} 126cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 127c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramervoid ExprEngine::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *expr, 128c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramer ExplodedNode *Pred, 129c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramer ExplodedNodeSet &Dst) { 130c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramer VisitCXXConstructExpr(expr, 0, Pred, Dst); 131c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramer} 132c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramer 133d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, 1345fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek const MemRegion *Dest, 1355fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek ExplodedNode *Pred, 1365fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek ExplodedNodeSet &destNodes) { 137cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 138cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu const CXXConstructorDecl *CD = E->getConstructor(); 139cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu assert(CD); 1405fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 1415fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek#if 0 14210620eb5164e31208fcbf0437cd79ae535ed0559Sean Hunt if (!(CD->doesThisDeclarationHaveABody() && AMgr.shouldInlineCall())) 143cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu // FIXME: invalidate the object. 144cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu return; 1455fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek#endif 146cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 147cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu // Evaluate other arguments. 1489c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek ExplodedNodeSet argsEvaluated; 149107ccd1f56836ae57c1a5a9c13c881b0293d1e98Zhongxing Xu const FunctionProtoType *FnType = CD->getType()->getAs<FunctionProtoType>(); 1509c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek evalArguments(E->arg_begin(), E->arg_end(), FnType, Pred, argsEvaluated); 1515fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 1525fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek#if 0 1535fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek // Is the constructor elidable? 1545fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek if (E->isElidable()) { 1555fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek VisitAggExpr(E->getArg(0), destNodes, Pred, Dst); 156fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner // FIXME: this is here to force propagation if VisitAggExpr doesn't 1575fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek if (destNodes.empty()) 1585fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek destNodes.Add(Pred); 1595fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek return; 1605fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek } 1615fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek#endif 1625fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 1635fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek // Perform the previsit of the constructor. 1645fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek ExplodedNodeSet destPreVisit; 1655fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek getCheckerManager().runCheckersForPreStmt(destPreVisit, argsEvaluated, E, 1665fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek *this); 1675fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 1685fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek // Evaluate the constructor. Currently we don't now allow checker-specific 1695fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek // implementations of specific constructors (as we do with ordinary 1705fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek // function calls. We can re-evaluate this in the future. 1715fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 1725fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek#if 0 1735fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek // Inlining currently isn't fully implemented. 1745fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 1755fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek if (AMgr.shouldInlineCall()) { 1765fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek if (!Dest) 1775fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek Dest = 1785fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek svalBuilder.getRegionManager().getCXXTempObjectRegion(E, 1795fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek Pred->getLocationContext()); 1805fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 1815fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek // The callee stack frame context used to create the 'this' 1825fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek // parameter region. 1835fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek const StackFrameContext *SFC = 1845fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek AMgr.getStackFrame(CD, Pred->getLocationContext(), 185ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks E, currentBuilderContext->getBlock(), 186ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks currentStmtIdx); 1875fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 1885fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek // Create the 'this' region. 1895fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek const CXXThisRegion *ThisR = 1905fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek getCXXThisRegion(E->getConstructor()->getParent(), SFC); 1915fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 1925fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek CallEnter Loc(E, SFC, Pred->getLocationContext()); 1935fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 194aa0aeb1cbe117db68d35700cb3a34aace0f99b99Anna Zaks StmtNodeBuilder Bldr(argsEvaluated, destNodes, *currentBuilderContext); 1955fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek for (ExplodedNodeSet::iterator NI = argsEvaluated.begin(), 1965fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek NE = argsEvaluated.end(); NI != NE; ++NI) { 1978bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = (*NI)->getState(); 1985fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek // Setup 'this' region, so that the ctor is evaluated on the object pointed 1995fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek // by 'Dest'. 2005fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest)); 201ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(Loc, *NI, state); 2025fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek } 203cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu } 2045fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek#endif 2055fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 2065fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek // Default semantics: invalidate all regions passed as arguments. 2075fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek ExplodedNodeSet destCall; 2085fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek { 209aa0aeb1cbe117db68d35700cb3a34aace0f99b99Anna Zaks StmtNodeBuilder Bldr(destPreVisit, destCall, *currentBuilderContext); 210ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks for (ExplodedNodeSet::iterator 211ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks i = destPreVisit.begin(), e = destPreVisit.end(); 212ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks i != e; ++i) 213ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks { 214ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNode *Pred = *i; 215ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks const LocationContext *LC = Pred->getLocationContext(); 2168bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 2175fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 2185eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state = invalidateArguments(state, CallOrObjCMessage(E, state, LC), LC); 219ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(E, Pred, state); 220ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks } 2215fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek } 2225fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek // Do the post visit. 2235fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek getCheckerManager().runCheckersForPostStmt(destNodes, destCall, E, *this); 224cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu} 225cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 226d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXDestructor(const CXXDestructorDecl *DD, 227ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks const MemRegion *Dest, 228ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks const Stmt *S, 229ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNode *Pred, 230ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNodeSet &Dst) { 231aa0aeb1cbe117db68d35700cb3a34aace0f99b99Anna Zaks StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 23210620eb5164e31208fcbf0437cd79ae535ed0559Sean Hunt if (!(DD->doesThisDeclarationHaveABody() && AMgr.shouldInlineCall())) 233b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu return; 234b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek 235b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu // Create the context for 'this' region. 236b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek const StackFrameContext *SFC = 2371d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek AnalysisDeclContexts.getContext(DD)-> 238b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek getStackFrame(Pred->getLocationContext(), S, 239ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks currentBuilderContext->getBlock(), currentStmtIdx); 240b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu 241b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu const CXXThisRegion *ThisR = getCXXThisRegion(DD->getParent(), SFC); 242b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu 24319b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu CallEnter PP(S, SFC, Pred->getLocationContext()); 244b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu 2458bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 246b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest)); 247ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(PP, Pred, state); 248b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu} 249b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu 250d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 251cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu ExplodedNodeSet &Dst) { 252aa0aeb1cbe117db68d35700cb3a34aace0f99b99Anna Zaks StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 25341c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek 254ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks unsigned blockCount = currentBuilderContext->getCurrentBlockCount(); 2553133f79cf451e6302dd05262b4bb53a3e4fd6300Ted Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 256c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek DefinedOrUnknownSVal symVal = 2573133f79cf451e6302dd05262b4bb53a3e4fd6300Ted Kremenek svalBuilder.getConjuredSymbolVal(NULL, CNE, LCtx, CNE->getType(), blockCount); 25841c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion(); 259cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType(); 260cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu const ElementRegion *EleReg = 26141c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek getStoreManager().GetElementZeroRegion(NewReg, ObjTy); 26241c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek 26341c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek if (CNE->isArray()) { 26441c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek // FIXME: allocating an array requires simulating the constructors. 26541c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek // For now, just return a symbolicated region. 2668bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 2675eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state = state->BindExpr(CNE, Pred->getLocationContext(), 2685eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek loc::MemRegionVal(EleReg)); 269ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(CNE, Pred, state); 27041c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek return; 27141c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek } 272cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 2732aed8b88613863f3c439cdfb205bdf8b608fb205Sebastian Redl // FIXME: Update for AST changes. 2742aed8b88613863f3c439cdfb205bdf8b608fb205Sebastian Redl#if 0 275b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu // Evaluate constructor arguments. 276b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu const FunctionProtoType *FnType = NULL; 277b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu const CXXConstructorDecl *CD = CNE->getConstructor(); 278b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu if (CD) 279b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu FnType = CD->getType()->getAs<FunctionProtoType>(); 2809c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek ExplodedNodeSet argsEvaluated; 281ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 2829c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek evalArguments(CNE->constructor_arg_begin(), CNE->constructor_arg_end(), 2839c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek FnType, Pred, argsEvaluated); 284ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(argsEvaluated); 285cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 286b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu // Initialize the object region and bind the 'new' expression. 2879c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek for (ExplodedNodeSet::iterator I = argsEvaluated.begin(), 2889c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek E = argsEvaluated.end(); I != E; ++I) { 2899d5d308c9be367ec41cc6a89f215d45f675b4617Ted Kremenek 2908bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = (*I)->getState(); 2919d5d308c9be367ec41cc6a89f215d45f675b4617Ted Kremenek 2929d5d308c9be367ec41cc6a89f215d45f675b4617Ted Kremenek // Accumulate list of regions that are invalidated. 2939d5d308c9be367ec41cc6a89f215d45f675b4617Ted Kremenek // FIXME: Eventually we should unify the logic for constructor 2949d5d308c9be367ec41cc6a89f215d45f675b4617Ted Kremenek // processing in one place. 2955f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<const MemRegion*, 10> regionsToInvalidate; 2969d5d308c9be367ec41cc6a89f215d45f675b4617Ted Kremenek for (CXXNewExpr::const_arg_iterator 2979d5d308c9be367ec41cc6a89f215d45f675b4617Ted Kremenek ai = CNE->constructor_arg_begin(), ae = CNE->constructor_arg_end(); 2989d5d308c9be367ec41cc6a89f215d45f675b4617Ted Kremenek ai != ae; ++ai) 2999d5d308c9be367ec41cc6a89f215d45f675b4617Ted Kremenek { 3005eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal val = state->getSVal(*ai, (*I)->getLocationContext()); 3019d5d308c9be367ec41cc6a89f215d45f675b4617Ted Kremenek if (const MemRegion *region = val.getAsRegion()) 3029d5d308c9be367ec41cc6a89f215d45f675b4617Ted Kremenek regionsToInvalidate.push_back(region); 3039d5d308c9be367ec41cc6a89f215d45f675b4617Ted Kremenek } 304b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu 305b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu if (ObjTy->isRecordType()) { 3069d5d308c9be367ec41cc6a89f215d45f675b4617Ted Kremenek regionsToInvalidate.push_back(EleReg); 3079d5d308c9be367ec41cc6a89f215d45f675b4617Ted Kremenek // Invalidate the regions. 308eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaks // TODO: Pass the call to new information as the last argument, to limit 309eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaks // the globals which will get invalidated. 310537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose state = state->invalidateRegions(regionsToInvalidate, 311eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaks CNE, blockCount, 0, 0); 3129d5d308c9be367ec41cc6a89f215d45f675b4617Ted Kremenek 313b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu } else { 3149d5d308c9be367ec41cc6a89f215d45f675b4617Ted Kremenek // Invalidate the regions. 315eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaks // TODO: Pass the call to new information as the last argument, to limit 316eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaks // the globals which will get invalidated. 317537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose state = state->invalidateRegions(regionsToInvalidate, 318eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaks CNE, blockCount, 0, 0); 3199d5d308c9be367ec41cc6a89f215d45f675b4617Ted Kremenek 320b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu if (CNE->hasInitializer()) { 3215eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal V = state->getSVal(*CNE->constructor_arg_begin(), 3225eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek (*I)->getLocationContext()); 323b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu state = state->bindLoc(loc::MemRegionVal(EleReg), V); 324b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu } else { 325b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu // Explicitly set to undefined, because currently we retrieve symbolic 326b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu // value from symbolic region. 327b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu state = state->bindLoc(loc::MemRegionVal(EleReg), UndefinedVal()); 328b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu } 329b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu } 3305eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state = state->BindExpr(CNE, (*I)->getLocationContext(), 3315eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek loc::MemRegionVal(EleReg)); 332ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(CNE, *I, state); 333b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu } 3342aed8b88613863f3c439cdfb205bdf8b608fb205Sebastian Redl#endif 335cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu} 336cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 337d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, 338ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNode *Pred, ExplodedNodeSet &Dst) { 3394fafeb6452a79794726a1adc53fb5e2a5887c5f9Erik Verbruggen StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 3404fafeb6452a79794726a1adc53fb5e2a5887c5f9Erik Verbruggen ProgramStateRef state = Pred->getState(); 3414fafeb6452a79794726a1adc53fb5e2a5887c5f9Erik Verbruggen Bldr.generateNode(CDE, Pred, state); 3426b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu} 343cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 344337e4dbc6859589b8878146a88bebf754e916702Ted Kremenekvoid ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS, 345337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek ExplodedNode *Pred, 346337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek ExplodedNodeSet &Dst) { 347337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek const VarDecl *VD = CS->getExceptionDecl(); 348337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 349337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek SVal V = svalBuilder.getConjuredSymbolVal(CS, LCtx, VD->getType(), 350337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek currentBuilderContext->getCurrentBlockCount()); 351337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek ProgramStateRef state = Pred->getState(); 352337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek state = state->bindLoc(state->getLValue(VD, LCtx), V); 353337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek 354337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 355337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek Bldr.generateNode(CS, Pred, state); 356337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek} 357337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek 358d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 3596b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu ExplodedNodeSet &Dst) { 360aa0aeb1cbe117db68d35700cb3a34aace0f99b99Anna Zaks StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 361ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 362cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu // Get the this object region from StoreManager. 3635eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 364cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu const MemRegion *R = 365c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek svalBuilder.getRegionManager().getCXXThisRegion( 366cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu getContext().getCanonicalType(TE->getType()), 3675eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek LCtx); 368cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 3698bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 370cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu SVal V = state->getSVal(loc::MemRegionVal(R)); 3715eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V)); 372cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu} 373