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" 17f540c54701e3eeb34cb619a3a4eb18f1ac70ef2dJordan Rose#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 18cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu#include "clang/AST/DeclCXX.h" 19337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek#include "clang/AST/StmtCXX.h" 20563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose#include "clang/Basic/PrettyStackTrace.h" 21cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 22cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xuusing namespace clang; 239ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento; 24cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 25eea72a925f294225391ecec876a342771c09b635Ted Kremenekvoid ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, 26eea72a925f294225391ecec876a342771c09b635Ted Kremenek ExplodedNode *Pred, 27eea72a925f294225391ecec876a342771c09b635Ted Kremenek ExplodedNodeSet &Dst) { 2866c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 296a835dddf45922e71a87637fdfac0863de65123cTed Kremenek const Expr *tempExpr = ME->GetTemporaryExpr()->IgnoreParens(); 308bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 315eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 32cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 336a835dddf45922e71a87637fdfac0863de65123cTed Kremenek // Bind the temporary object to the value of the expression. Then bind 346a835dddf45922e71a87637fdfac0863de65123cTed Kremenek // the expression to the location of the object. 35c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose SVal V = state->getSVal(tempExpr, LCtx); 36cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 376ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose // If the value is already a CXXTempObjectRegion, it is fine as it is. 386ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose // Otherwise, create a new CXXTempObjectRegion, and copy the value into it. 396ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose const MemRegion *MR = V.getAsRegion(); 406ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose if (!MR || !isa<CXXTempObjectRegion>(MR)) { 41c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose const MemRegion *R = 42c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose svalBuilder.getRegionManager().getCXXTempObjectRegion(ME, LCtx); 43cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 44c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose SVal L = loc::MemRegionVal(R); 45c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose state = state->bindLoc(L, V); 46c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose V = L; 47c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose } 48c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose 49c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose Bldr.generateNode(ME, Pred, state->BindExpr(ME, LCtx, V)); 50cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu} 51cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 52362a31cacc19764f3630928a9e4779af2576e074Jordan Rosevoid ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE, 535fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek ExplodedNode *Pred, 545fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek ExplodedNodeSet &destNodes) { 55888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 56075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose ProgramStateRef State = Pred->getState(); 57075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose 58888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const MemRegion *Target = 0; 59888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 60888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose switch (CE->getConstructionKind()) { 61888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose case CXXConstructExpr::CK_Complete: { 62075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose // See if we're constructing an existing region by looking at the next 63075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose // element in the CFG. 6466c486f275531df6362b3511fc3af6563561801bTed Kremenek const CFGBlock *B = currBldrCtx->getBlock(); 6566c486f275531df6362b3511fc3af6563561801bTed Kremenek if (currStmtIdx + 1 < B->size()) { 6666c486f275531df6362b3511fc3af6563561801bTed Kremenek CFGElement Next = (*B)[currStmtIdx+1]; 67075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose 68075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose // Is this a constructor for a local variable? 69e460c46c5d602f65354cab0879c458890273591cJordan Rose if (const CFGStmt *StmtElem = dyn_cast<CFGStmt>(&Next)) { 70e460c46c5d602f65354cab0879c458890273591cJordan Rose if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) { 71e460c46c5d602f65354cab0879c458890273591cJordan Rose if (const VarDecl *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) { 72e460c46c5d602f65354cab0879c458890273591cJordan Rose if (Var->getInit()->IgnoreImplicit() == CE) { 73e460c46c5d602f65354cab0879c458890273591cJordan Rose QualType Ty = Var->getType(); 74e460c46c5d602f65354cab0879c458890273591cJordan Rose if (const ArrayType *AT = getContext().getAsArrayType(Ty)) { 75e460c46c5d602f65354cab0879c458890273591cJordan Rose // FIXME: Handle arrays, which run the same constructor for 76e460c46c5d602f65354cab0879c458890273591cJordan Rose // every element. This workaround will just run the first 77e460c46c5d602f65354cab0879c458890273591cJordan Rose // constructor (which should still invalidate the entire array). 78e460c46c5d602f65354cab0879c458890273591cJordan Rose SVal Base = State->getLValue(Var, LCtx); 79e460c46c5d602f65354cab0879c458890273591cJordan Rose Target = State->getLValue(AT->getElementType(), 80e460c46c5d602f65354cab0879c458890273591cJordan Rose getSValBuilder().makeZeroArrayIndex(), 81e460c46c5d602f65354cab0879c458890273591cJordan Rose Base).getAsRegion(); 82e460c46c5d602f65354cab0879c458890273591cJordan Rose } else { 83e460c46c5d602f65354cab0879c458890273591cJordan Rose Target = State->getLValue(Var, LCtx).getAsRegion(); 84e460c46c5d602f65354cab0879c458890273591cJordan Rose } 85e460c46c5d602f65354cab0879c458890273591cJordan Rose } 86e460c46c5d602f65354cab0879c458890273591cJordan Rose } 87e460c46c5d602f65354cab0879c458890273591cJordan Rose } 88e460c46c5d602f65354cab0879c458890273591cJordan Rose } 89e460c46c5d602f65354cab0879c458890273591cJordan Rose 903a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose // Is this a constructor for a member? 913a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose if (const CFGInitializer *InitElem = dyn_cast<CFGInitializer>(&Next)) { 923a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose const CXXCtorInitializer *Init = InitElem->getInitializer(); 933a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose assert(Init->isAnyMemberInitializer()); 943a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 953a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl()); 963a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor, 973a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose LCtx->getCurrentStackFrame()); 983a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose SVal ThisVal = State->getSVal(ThisPtr); 993a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 1003a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose if (Init->isIndirectMemberInitializer()) { 1013a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose SVal Field = State->getLValue(Init->getIndirectMember(), ThisVal); 102e460c46c5d602f65354cab0879c458890273591cJordan Rose Target = Field.getAsRegion(); 1033a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose } else { 1043a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose SVal Field = State->getLValue(Init->getMember(), ThisVal); 105e460c46c5d602f65354cab0879c458890273591cJordan Rose Target = Field.getAsRegion(); 1063a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose } 1073a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose } 1083a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 109075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose // FIXME: This will eventually need to handle new-expressions as well. 110075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose } 111075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose 112c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose // If we couldn't find an existing region to construct into, assume we're 113c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose // constructing a temporary. 114c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose if (!Target) { 115c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose MemRegionManager &MRMgr = getSValBuilder().getRegionManager(); 116c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose Target = MRMgr.getCXXTempObjectRegion(CE, LCtx); 117c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose } 118075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose 119888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose break; 120888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose } 121888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose case CXXConstructExpr::CK_NonVirtualBase: 122888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose case CXXConstructExpr::CK_VirtualBase: 123888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose case CXXConstructExpr::CK_Delegating: { 124888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl()); 125888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor, 126888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose LCtx->getCurrentStackFrame()); 127075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose SVal ThisVal = State->getSVal(ThisPtr); 128888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 129888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose if (CE->getConstructionKind() == CXXConstructExpr::CK_Delegating) { 130888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose Target = ThisVal.getAsRegion(); 131888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose } else { 132888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose // Cast to the base type. 133888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose QualType BaseTy = CE->getType(); 134888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, BaseTy); 135e460c46c5d602f65354cab0879c458890273591cJordan Rose Target = BaseVal.getAsRegion(); 136888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose } 137888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose break; 138888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose } 139888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose } 140888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 141d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CallEventManager &CEMgr = getStateManager().getCallEventManager(); 142d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CallEventRef<CXXConstructorCall> Call = 143d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CEMgr.getCXXConstructorCall(CE, Target, State, LCtx); 144cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 145362a31cacc19764f3630928a9e4779af2576e074Jordan Rose ExplodedNodeSet DstPreVisit; 146362a31cacc19764f3630928a9e4779af2576e074Jordan Rose getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this); 14796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose ExplodedNodeSet DstPreCall; 14896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose getCheckerManager().runCheckersForPreCall(DstPreCall, DstPreVisit, 149d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose *Call, *this); 1505fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 151362a31cacc19764f3630928a9e4779af2576e074Jordan Rose ExplodedNodeSet DstInvalidated; 15266c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx); 15396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 154362a31cacc19764f3630928a9e4779af2576e074Jordan Rose I != E; ++I) 155d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose defaultEvalCall(Bldr, *I, *Call); 1565fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 15796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose ExplodedNodeSet DstPostCall; 15896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose getCheckerManager().runCheckersForPostCall(DstPostCall, DstInvalidated, 159d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose *Call, *this); 16096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this); 161cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu} 162cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 163888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rosevoid ExprEngine::VisitCXXDestructor(QualType ObjectType, 164888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const MemRegion *Dest, 165888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const Stmt *S, 166200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose bool IsBaseDtor, 167888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose ExplodedNode *Pred, 168888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose ExplodedNodeSet &Dst) { 169d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 170d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose ProgramStateRef State = Pred->getState(); 171d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose 172e460c46c5d602f65354cab0879c458890273591cJordan Rose // FIXME: We need to run the same destructor on every element of the array. 173e460c46c5d602f65354cab0879c458890273591cJordan Rose // This workaround will just run the first destructor (which will still 174e460c46c5d602f65354cab0879c458890273591cJordan Rose // invalidate the entire array). 175e460c46c5d602f65354cab0879c458890273591cJordan Rose if (const ArrayType *AT = getContext().getAsArrayType(ObjectType)) { 176e460c46c5d602f65354cab0879c458890273591cJordan Rose ObjectType = AT->getElementType(); 177d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose Dest = State->getLValue(ObjectType, getSValBuilder().makeZeroArrayIndex(), 178d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose loc::MemRegionVal(Dest)).getAsRegion(); 179e460c46c5d602f65354cab0879c458890273591cJordan Rose } 180e460c46c5d602f65354cab0879c458890273591cJordan Rose 181888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl(); 182888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose assert(RecordDecl && "Only CXXRecordDecls should have destructors"); 183888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor(); 184888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 185d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CallEventManager &CEMgr = getStateManager().getCallEventManager(); 186d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CallEventRef<CXXDestructorCall> Call = 187200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose CEMgr.getCXXDestructorCall(DtorDecl, S, Dest, IsBaseDtor, State, LCtx); 188b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek 189563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 190563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose Call->getSourceRange().getBegin(), 191563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose "Error evaluating destructor"); 192563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose 1938d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose ExplodedNodeSet DstPreCall; 1948d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, 195d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose *Call, *this); 196b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu 1978d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose ExplodedNodeSet DstInvalidated; 19866c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx); 1998d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 2008d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose I != E; ++I) 201d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose defaultEvalCall(Bldr, *I, *Call); 2028d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose 2038d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose ExplodedNodeSet DstPostCall; 2048d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated, 205d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose *Call, *this); 206b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu} 207b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu 208d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 209cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu ExplodedNodeSet &Dst) { 21070cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // FIXME: Much of this should eventually migrate to CXXAllocatorCall. 21170cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // Also, we need to decide how allocators actually work -- they're not 21270cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // really part of the CXXNewExpr because they happen BEFORE the 21370cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // CXXConstructExpr subexpression. See PR12014 for some discussion. 21466c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 21541c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek 21666c486f275531df6362b3511fc3af6563561801bTed Kremenek unsigned blockCount = currBldrCtx->blockCount(); 2173133f79cf451e6302dd05262b4bb53a3e4fd6300Ted Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 2183b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek DefinedOrUnknownSVal symVal = svalBuilder.conjureSymbolVal(0, CNE, LCtx, 2193b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek CNE->getType(), 2203b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek blockCount); 221e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose ProgramStateRef State = Pred->getState(); 22241c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek 223d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CallEventManager &CEMgr = getStateManager().getCallEventManager(); 224d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CallEventRef<CXXAllocatorCall> Call = 225d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CEMgr.getCXXAllocatorCall(CNE, State, LCtx); 226d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose 22770cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // Invalidate placement args. 228d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose // FIXME: Once we figure out how we want allocators to work, 229d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose // we should be using the usual pre-/(default-)eval-/post-call checks here. 230d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose State = Call->invalidateRegions(blockCount); 23170cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose 23241c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek if (CNE->isArray()) { 23341c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek // FIXME: allocating an array requires simulating the constructors. 23441c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek // For now, just return a symbolicated region. 23570cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion(); 23670cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType(); 23770cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose const ElementRegion *EleReg = 23870cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose getStoreManager().GetElementZeroRegion(NewReg, ObjTy); 239e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose State = State->BindExpr(CNE, Pred->getLocationContext(), 2405eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek loc::MemRegionVal(EleReg)); 241e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose Bldr.generateNode(CNE, Pred, State); 24241c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek return; 24341c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek } 244cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 24570cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // FIXME: Once we have proper support for CXXConstructExprs inside 24670cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // CXXNewExpr, we need to make sure that the constructed object is not 24770cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // immediately invalidated here. (The placement call should happen before 24870cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // the constructor call anyway.) 249e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose FunctionDecl *FD = CNE->getOperatorNew(); 250e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose if (FD && FD->isReservedGlobalPlacementOperator()) { 251e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose // Non-array placement new should always return the placement location. 252e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx); 2539874f597ef5d5748695c88daaa9a3208f95c2032Jordan Rose SVal Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(), 2549874f597ef5d5748695c88daaa9a3208f95c2032Jordan Rose CNE->getPlacementArg(0)->getType()); 2559874f597ef5d5748695c88daaa9a3208f95c2032Jordan Rose State = State->BindExpr(CNE, LCtx, Result); 25670cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose } else { 25770cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose State = State->BindExpr(CNE, LCtx, symVal); 258e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose } 259e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose 26089e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose // If the type is not a record, we won't have a CXXConstructExpr as an 26189e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose // initializer. Copy the value over. 26289e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose if (const Expr *Init = CNE->getInitializer()) { 26389e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose if (!isa<CXXConstructExpr>(Init)) { 26489e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType(); 26589e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose (void)ObjTy; 26689e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose assert(!ObjTy->isRecordType()); 26789e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose SVal Location = State->getSVal(CNE, LCtx); 26889e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose if (isa<Loc>(Location)) 26989e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose State = State->bindLoc(cast<Loc>(Location), State->getSVal(Init, LCtx)); 27089e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose } 27189e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose } 27289e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose 273e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose Bldr.generateNode(CNE, Pred, State); 274cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu} 275cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 276d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, 277ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNode *Pred, ExplodedNodeSet &Dst) { 27866c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 2794fafeb6452a79794726a1adc53fb5e2a5887c5f9Erik Verbruggen ProgramStateRef state = Pred->getState(); 2804fafeb6452a79794726a1adc53fb5e2a5887c5f9Erik Verbruggen Bldr.generateNode(CDE, Pred, state); 2816b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu} 282cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 283337e4dbc6859589b8878146a88bebf754e916702Ted Kremenekvoid ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS, 284337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek ExplodedNode *Pred, 285337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek ExplodedNodeSet &Dst) { 286337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek const VarDecl *VD = CS->getExceptionDecl(); 287ce612f5a7d306f919c7ae57fcd8c5ecb5d83d54eTed Kremenek if (!VD) { 288ce612f5a7d306f919c7ae57fcd8c5ecb5d83d54eTed Kremenek Dst.Add(Pred); 289ce612f5a7d306f919c7ae57fcd8c5ecb5d83d54eTed Kremenek return; 290ce612f5a7d306f919c7ae57fcd8c5ecb5d83d54eTed Kremenek } 291ce612f5a7d306f919c7ae57fcd8c5ecb5d83d54eTed Kremenek 292337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 2933b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(), 29466c486f275531df6362b3511fc3af6563561801bTed Kremenek currBldrCtx->blockCount()); 295337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek ProgramStateRef state = Pred->getState(); 296337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek state = state->bindLoc(state->getLValue(VD, LCtx), V); 297337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek 29866c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 299337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek Bldr.generateNode(CS, Pred, state); 300337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek} 301337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek 302d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 3036b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu ExplodedNodeSet &Dst) { 30466c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 305ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 306cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu // Get the this object region from StoreManager. 3075eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 308cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu const MemRegion *R = 309c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek svalBuilder.getRegionManager().getCXXThisRegion( 310cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu getContext().getCanonicalType(TE->getType()), 3115eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek LCtx); 312cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 3138bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 314cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu SVal V = state->getSVal(loc::MemRegionVal(R)); 3155eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V)); 316cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu} 317