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 149b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 15cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu#include "clang/AST/DeclCXX.h" 16337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek#include "clang/AST/StmtCXX.h" 17563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose#include "clang/Basic/PrettyStackTrace.h" 1855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/CheckerManager.h" 1955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.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 33c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose SVal V = state->getSVal(tempExpr, LCtx); 34cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 356ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose // If the value is already a CXXTempObjectRegion, it is fine as it is. 366ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose // Otherwise, create a new CXXTempObjectRegion, and copy the value into it. 37eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose // This is an optimization for when an rvalue is constructed and then 38eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose // immediately materialized. 396ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose const MemRegion *MR = V.getAsRegion(); 40eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose if (const CXXTempObjectRegion *TR = 41eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose dyn_cast_or_null<CXXTempObjectRegion>(MR)) { 42eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose if (getContext().hasSameUnqualifiedType(TR->getValueType(), ME->getType())) 43eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose state = state->BindExpr(ME, LCtx, V); 44eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose } 45cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 46eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose if (state == Pred->getState()) 47eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose state = createTemporaryRegionIfNeeded(state, LCtx, tempExpr, ME); 485e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose Bldr.generateNode(ME, Pred, state); 49cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu} 50cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 51a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose// FIXME: This is the sort of code that should eventually live in a Core 52a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose// checker rather than as a special case in ExprEngine. 53bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rosevoid ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred, 54a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose const CallEvent &Call) { 55a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose SVal ThisVal; 56a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose bool AlwaysReturnsLValue; 57a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose if (const CXXConstructorCall *Ctor = dyn_cast<CXXConstructorCall>(&Call)) { 58a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose assert(Ctor->getDecl()->isTrivial()); 59a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose assert(Ctor->getDecl()->isCopyOrMoveConstructor()); 60a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose ThisVal = Ctor->getCXXThisVal(); 61a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose AlwaysReturnsLValue = false; 62a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose } else { 63a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose assert(cast<CXXMethodDecl>(Call.getDecl())->isTrivial()); 64a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose assert(cast<CXXMethodDecl>(Call.getDecl())->getOverloadedOperator() == 65a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose OO_Equal); 66a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose ThisVal = cast<CXXInstanceCall>(Call).getCXXThisVal(); 67a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose AlwaysReturnsLValue = true; 68a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose } 69bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose 70bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 71bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose 72bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose ExplodedNodeSet Dst; 73bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose Bldr.takeNodes(Pred); 74bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose 75bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose SVal V = Call.getArgSVal(0); 76bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose 77a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose // If the value being copied is not unknown, load from its location to get 78a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose // an aggregate rvalue. 79dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie if (Optional<Loc> L = V.getAs<Loc>()) 80bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose V = Pred->getState()->getSVal(*L); 81a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose else 82a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose assert(V.isUnknown()); 83bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose 84a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose const Expr *CallExpr = Call.getOriginExpr(); 85a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose evalBind(Dst, CallExpr, Pred, ThisVal, V, true); 86bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose 87a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose PostStmt PS(CallExpr, LCtx); 88bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose for (ExplodedNodeSet::iterator I = Dst.begin(), E = Dst.end(); 89bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose I != E; ++I) { 90bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose ProgramStateRef State = (*I)->getState(); 91a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose if (AlwaysReturnsLValue) 92a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose State = State->BindExpr(CallExpr, LCtx, ThisVal); 93a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose else 94a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose State = bindReturnValue(Call, LCtx, State); 95bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose Bldr.generateNode(PS, State, *I); 96bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose } 97bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose} 98bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose 99362a31cacc19764f3630928a9e4779af2576e074Jordan Rosevoid ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE, 1005fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek ExplodedNode *Pred, 1015fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek ExplodedNodeSet &destNodes) { 102888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 103075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose ProgramStateRef State = Pred->getState(); 104075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose 105888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const MemRegion *Target = 0; 106bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose bool IsArray = false; 107888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 108888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose switch (CE->getConstructionKind()) { 109888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose case CXXConstructExpr::CK_Complete: { 110075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose // See if we're constructing an existing region by looking at the next 111075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose // element in the CFG. 11266c486f275531df6362b3511fc3af6563561801bTed Kremenek const CFGBlock *B = currBldrCtx->getBlock(); 11366c486f275531df6362b3511fc3af6563561801bTed Kremenek if (currStmtIdx + 1 < B->size()) { 11466c486f275531df6362b3511fc3af6563561801bTed Kremenek CFGElement Next = (*B)[currStmtIdx+1]; 115075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose 116075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose // Is this a constructor for a local variable? 117b07805485c603be3d8011f72611465324c9e664bDavid Blaikie if (Optional<CFGStmt> StmtElem = Next.getAs<CFGStmt>()) { 118b07805485c603be3d8011f72611465324c9e664bDavid Blaikie if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) { 119e460c46c5d602f65354cab0879c458890273591cJordan Rose if (const VarDecl *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) { 120e460c46c5d602f65354cab0879c458890273591cJordan Rose if (Var->getInit()->IgnoreImplicit() == CE) { 121e460c46c5d602f65354cab0879c458890273591cJordan Rose QualType Ty = Var->getType(); 122e460c46c5d602f65354cab0879c458890273591cJordan Rose if (const ArrayType *AT = getContext().getAsArrayType(Ty)) { 123e460c46c5d602f65354cab0879c458890273591cJordan Rose // FIXME: Handle arrays, which run the same constructor for 124e460c46c5d602f65354cab0879c458890273591cJordan Rose // every element. This workaround will just run the first 125e460c46c5d602f65354cab0879c458890273591cJordan Rose // constructor (which should still invalidate the entire array). 126e460c46c5d602f65354cab0879c458890273591cJordan Rose SVal Base = State->getLValue(Var, LCtx); 127e460c46c5d602f65354cab0879c458890273591cJordan Rose Target = State->getLValue(AT->getElementType(), 128e460c46c5d602f65354cab0879c458890273591cJordan Rose getSValBuilder().makeZeroArrayIndex(), 129e460c46c5d602f65354cab0879c458890273591cJordan Rose Base).getAsRegion(); 130bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose IsArray = true; 131e460c46c5d602f65354cab0879c458890273591cJordan Rose } else { 132e460c46c5d602f65354cab0879c458890273591cJordan Rose Target = State->getLValue(Var, LCtx).getAsRegion(); 133e460c46c5d602f65354cab0879c458890273591cJordan Rose } 134e460c46c5d602f65354cab0879c458890273591cJordan Rose } 135e460c46c5d602f65354cab0879c458890273591cJordan Rose } 136e460c46c5d602f65354cab0879c458890273591cJordan Rose } 137e460c46c5d602f65354cab0879c458890273591cJordan Rose } 138e460c46c5d602f65354cab0879c458890273591cJordan Rose 1393a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose // Is this a constructor for a member? 140b07805485c603be3d8011f72611465324c9e664bDavid Blaikie if (Optional<CFGInitializer> InitElem = Next.getAs<CFGInitializer>()) { 141b07805485c603be3d8011f72611465324c9e664bDavid Blaikie const CXXCtorInitializer *Init = InitElem->getInitializer(); 1423a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose assert(Init->isAnyMemberInitializer()); 1433a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 1443a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl()); 1453a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor, 1463a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose LCtx->getCurrentStackFrame()); 1473a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose SVal ThisVal = State->getSVal(ThisPtr); 1483a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 1493a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose if (Init->isIndirectMemberInitializer()) { 1503a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose SVal Field = State->getLValue(Init->getIndirectMember(), ThisVal); 151e460c46c5d602f65354cab0879c458890273591cJordan Rose Target = Field.getAsRegion(); 1523a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose } else { 1533a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose SVal Field = State->getLValue(Init->getMember(), ThisVal); 154e460c46c5d602f65354cab0879c458890273591cJordan Rose Target = Field.getAsRegion(); 1553a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose } 1563a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose } 1573a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 158075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose // FIXME: This will eventually need to handle new-expressions as well. 159075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose } 160075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose 161c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose // If we couldn't find an existing region to construct into, assume we're 162c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose // constructing a temporary. 163c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose if (!Target) { 164c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose MemRegionManager &MRMgr = getSValBuilder().getRegionManager(); 165c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose Target = MRMgr.getCXXTempObjectRegion(CE, LCtx); 166c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose } 167075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose 168888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose break; 169888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose } 170888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose case CXXConstructExpr::CK_NonVirtualBase: 171888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose case CXXConstructExpr::CK_VirtualBase: 172888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose case CXXConstructExpr::CK_Delegating: { 173888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl()); 174888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor, 175888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose LCtx->getCurrentStackFrame()); 176075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose SVal ThisVal = State->getSVal(ThisPtr); 177888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 178888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose if (CE->getConstructionKind() == CXXConstructExpr::CK_Delegating) { 179888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose Target = ThisVal.getAsRegion(); 180888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose } else { 181888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose // Cast to the base type. 1824411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose bool IsVirtual = 1834411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose (CE->getConstructionKind() == CXXConstructExpr::CK_VirtualBase); 1844411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, CE->getType(), 1854411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose IsVirtual); 186e460c46c5d602f65354cab0879c458890273591cJordan Rose Target = BaseVal.getAsRegion(); 187888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose } 188888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose break; 189888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose } 190888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose } 191888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 192d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CallEventManager &CEMgr = getStateManager().getCallEventManager(); 193d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CallEventRef<CXXConstructorCall> Call = 194d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CEMgr.getCXXConstructorCall(CE, Target, State, LCtx); 195cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 196362a31cacc19764f3630928a9e4779af2576e074Jordan Rose ExplodedNodeSet DstPreVisit; 197362a31cacc19764f3630928a9e4779af2576e074Jordan Rose getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this); 19896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose ExplodedNodeSet DstPreCall; 19996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose getCheckerManager().runCheckersForPreCall(DstPreCall, DstPreVisit, 200d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose *Call, *this); 2015fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 202bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose ExplodedNodeSet DstEvaluated; 203bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx); 204bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose 205bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose if (CE->getConstructor()->isTrivial() && 206bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose CE->getConstructor()->isCopyOrMoveConstructor() && 207bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose !IsArray) { 208bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose // FIXME: Handle other kinds of trivial constructors as well. 209bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 210bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose I != E; ++I) 211bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose performTrivialCopy(Bldr, *I, *Call); 212bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose 213bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose } else { 214bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 215bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose I != E; ++I) 216bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose defaultEvalCall(Bldr, *I, *Call); 217bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose } 2185fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 21996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose ExplodedNodeSet DstPostCall; 220bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated, 221d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose *Call, *this); 22296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this); 223cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu} 224cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 225888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rosevoid ExprEngine::VisitCXXDestructor(QualType ObjectType, 226888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const MemRegion *Dest, 227888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const Stmt *S, 228200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose bool IsBaseDtor, 229888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose ExplodedNode *Pred, 230888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose ExplodedNodeSet &Dst) { 231d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 232d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose ProgramStateRef State = Pred->getState(); 233d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose 234e460c46c5d602f65354cab0879c458890273591cJordan Rose // FIXME: We need to run the same destructor on every element of the array. 235e460c46c5d602f65354cab0879c458890273591cJordan Rose // This workaround will just run the first destructor (which will still 236e460c46c5d602f65354cab0879c458890273591cJordan Rose // invalidate the entire array). 2374f69eb4daa3c5ce8b88535fc560f2ee102a580f4Jordan Rose // This is a loop because of multidimensional arrays. 2384f69eb4daa3c5ce8b88535fc560f2ee102a580f4Jordan Rose while (const ArrayType *AT = getContext().getAsArrayType(ObjectType)) { 239e460c46c5d602f65354cab0879c458890273591cJordan Rose ObjectType = AT->getElementType(); 240d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose Dest = State->getLValue(ObjectType, getSValBuilder().makeZeroArrayIndex(), 241d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose loc::MemRegionVal(Dest)).getAsRegion(); 242e460c46c5d602f65354cab0879c458890273591cJordan Rose } 243e460c46c5d602f65354cab0879c458890273591cJordan Rose 244888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl(); 245888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose assert(RecordDecl && "Only CXXRecordDecls should have destructors"); 246888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor(); 247888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 248d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CallEventManager &CEMgr = getStateManager().getCallEventManager(); 249d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CallEventRef<CXXDestructorCall> Call = 250200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose CEMgr.getCXXDestructorCall(DtorDecl, S, Dest, IsBaseDtor, State, LCtx); 251b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek 252563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 253563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose Call->getSourceRange().getBegin(), 254563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose "Error evaluating destructor"); 255563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose 2568d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose ExplodedNodeSet DstPreCall; 2578d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, 258d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose *Call, *this); 259b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu 2608d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose ExplodedNodeSet DstInvalidated; 26166c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx); 2628d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 2638d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose I != E; ++I) 264d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose defaultEvalCall(Bldr, *I, *Call); 2658d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose 2668d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose ExplodedNodeSet DstPostCall; 2678d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated, 268d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose *Call, *this); 269b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu} 270b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu 271d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 272cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu ExplodedNodeSet &Dst) { 27370cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // FIXME: Much of this should eventually migrate to CXXAllocatorCall. 27470cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // Also, we need to decide how allocators actually work -- they're not 27570cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // really part of the CXXNewExpr because they happen BEFORE the 27670cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // CXXConstructExpr subexpression. See PR12014 for some discussion. 27766c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 27841c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek 27966c486f275531df6362b3511fc3af6563561801bTed Kremenek unsigned blockCount = currBldrCtx->blockCount(); 2803133f79cf451e6302dd05262b4bb53a3e4fd6300Ted Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 2813b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek DefinedOrUnknownSVal symVal = svalBuilder.conjureSymbolVal(0, CNE, LCtx, 2823b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek CNE->getType(), 2833b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek blockCount); 284e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose ProgramStateRef State = Pred->getState(); 28541c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek 286d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CallEventManager &CEMgr = getStateManager().getCallEventManager(); 287d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CallEventRef<CXXAllocatorCall> Call = 288d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CEMgr.getCXXAllocatorCall(CNE, State, LCtx); 289d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose 29070cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // Invalidate placement args. 291d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose // FIXME: Once we figure out how we want allocators to work, 292d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose // we should be using the usual pre-/(default-)eval-/post-call checks here. 293d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose State = Call->invalidateRegions(blockCount); 29470cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose 295b59b580a57a36df9d146473098d14c64508ff319Jordan Rose // If we're compiling with exceptions enabled, and this allocation function 296b59b580a57a36df9d146473098d14c64508ff319Jordan Rose // is not declared as non-throwing, failures /must/ be signalled by 297b59b580a57a36df9d146473098d14c64508ff319Jordan Rose // exceptions, and thus the return value will never be NULL. 298b59b580a57a36df9d146473098d14c64508ff319Jordan Rose // C++11 [basic.stc.dynamic.allocation]p3. 299b59b580a57a36df9d146473098d14c64508ff319Jordan Rose FunctionDecl *FD = CNE->getOperatorNew(); 300b59b580a57a36df9d146473098d14c64508ff319Jordan Rose if (FD && getContext().getLangOpts().CXXExceptions) { 301b59b580a57a36df9d146473098d14c64508ff319Jordan Rose QualType Ty = FD->getType(); 302b59b580a57a36df9d146473098d14c64508ff319Jordan Rose if (const FunctionProtoType *ProtoType = Ty->getAs<FunctionProtoType>()) 303b59b580a57a36df9d146473098d14c64508ff319Jordan Rose if (!ProtoType->isNothrow(getContext())) 304b59b580a57a36df9d146473098d14c64508ff319Jordan Rose State = State->assume(symVal, true); 305b59b580a57a36df9d146473098d14c64508ff319Jordan Rose } 306b59b580a57a36df9d146473098d14c64508ff319Jordan Rose 30741c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek if (CNE->isArray()) { 30841c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek // FIXME: allocating an array requires simulating the constructors. 30941c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek // For now, just return a symbolicated region. 3105251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie const MemRegion *NewReg = symVal.castAs<loc::MemRegionVal>().getRegion(); 31170cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType(); 31270cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose const ElementRegion *EleReg = 31370cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose getStoreManager().GetElementZeroRegion(NewReg, ObjTy); 314e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose State = State->BindExpr(CNE, Pred->getLocationContext(), 3155eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek loc::MemRegionVal(EleReg)); 316e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose Bldr.generateNode(CNE, Pred, State); 31741c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek return; 31841c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek } 319cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 32070cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // FIXME: Once we have proper support for CXXConstructExprs inside 32170cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // CXXNewExpr, we need to make sure that the constructed object is not 32270cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // immediately invalidated here. (The placement call should happen before 32370cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // the constructor call anyway.) 324e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose if (FD && FD->isReservedGlobalPlacementOperator()) { 325e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose // Non-array placement new should always return the placement location. 326e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx); 3279874f597ef5d5748695c88daaa9a3208f95c2032Jordan Rose SVal Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(), 3289874f597ef5d5748695c88daaa9a3208f95c2032Jordan Rose CNE->getPlacementArg(0)->getType()); 3299874f597ef5d5748695c88daaa9a3208f95c2032Jordan Rose State = State->BindExpr(CNE, LCtx, Result); 33070cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose } else { 33170cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose State = State->BindExpr(CNE, LCtx, symVal); 332e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose } 333e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose 33489e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose // If the type is not a record, we won't have a CXXConstructExpr as an 33589e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose // initializer. Copy the value over. 33689e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose if (const Expr *Init = CNE->getInitializer()) { 33789e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose if (!isa<CXXConstructExpr>(Init)) { 33889e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType(); 33989e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose (void)ObjTy; 34089e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose assert(!ObjTy->isRecordType()); 34189e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose SVal Location = State->getSVal(CNE, LCtx); 342dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie if (Optional<Loc> LV = Location.getAs<Loc>()) 3435251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie State = State->bindLoc(*LV, State->getSVal(Init, LCtx)); 34489e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose } 34589e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose } 34689e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose 347e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose Bldr.generateNode(CNE, Pred, State); 348cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu} 349cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 350d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, 351ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNode *Pred, ExplodedNodeSet &Dst) { 35266c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 3534fafeb6452a79794726a1adc53fb5e2a5887c5f9Erik Verbruggen ProgramStateRef state = Pred->getState(); 3544fafeb6452a79794726a1adc53fb5e2a5887c5f9Erik Verbruggen Bldr.generateNode(CDE, Pred, state); 3556b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu} 356cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 357337e4dbc6859589b8878146a88bebf754e916702Ted Kremenekvoid ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS, 358337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek ExplodedNode *Pred, 359337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek ExplodedNodeSet &Dst) { 360337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek const VarDecl *VD = CS->getExceptionDecl(); 361ce612f5a7d306f919c7ae57fcd8c5ecb5d83d54eTed Kremenek if (!VD) { 362ce612f5a7d306f919c7ae57fcd8c5ecb5d83d54eTed Kremenek Dst.Add(Pred); 363ce612f5a7d306f919c7ae57fcd8c5ecb5d83d54eTed Kremenek return; 364ce612f5a7d306f919c7ae57fcd8c5ecb5d83d54eTed Kremenek } 365ce612f5a7d306f919c7ae57fcd8c5ecb5d83d54eTed Kremenek 366337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 3673b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(), 36866c486f275531df6362b3511fc3af6563561801bTed Kremenek currBldrCtx->blockCount()); 369337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek ProgramStateRef state = Pred->getState(); 370337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek state = state->bindLoc(state->getLValue(VD, LCtx), V); 371337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek 37266c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 373337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek Bldr.generateNode(CS, Pred, state); 374337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek} 375337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek 376d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 3776b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu ExplodedNodeSet &Dst) { 37866c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 379ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 380cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu // Get the this object region from StoreManager. 3815eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 382cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu const MemRegion *R = 383c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek svalBuilder.getRegionManager().getCXXThisRegion( 384cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu getContext().getCanonicalType(TE->getType()), 3855eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek LCtx); 386cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 3878bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 388cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu SVal V = state->getSVal(loc::MemRegionVal(R)); 3895eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V)); 390cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu} 391