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 33b2c405eb22b2b4844ded1f865675329c2d9793edJordan Rose state = createTemporaryRegionIfNeeded(state, LCtx, tempExpr, ME); 345e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose Bldr.generateNode(ME, Pred, state); 35cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu} 36cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 37a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose// FIXME: This is the sort of code that should eventually live in a Core 38a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose// checker rather than as a special case in ExprEngine. 39bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rosevoid ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred, 40a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose const CallEvent &Call) { 41a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose SVal ThisVal; 42a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose bool AlwaysReturnsLValue; 43a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose if (const CXXConstructorCall *Ctor = dyn_cast<CXXConstructorCall>(&Call)) { 44a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose assert(Ctor->getDecl()->isTrivial()); 45a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose assert(Ctor->getDecl()->isCopyOrMoveConstructor()); 46a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose ThisVal = Ctor->getCXXThisVal(); 47a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose AlwaysReturnsLValue = false; 48a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose } else { 49a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose assert(cast<CXXMethodDecl>(Call.getDecl())->isTrivial()); 50a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose assert(cast<CXXMethodDecl>(Call.getDecl())->getOverloadedOperator() == 51a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose OO_Equal); 52a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose ThisVal = cast<CXXInstanceCall>(Call).getCXXThisVal(); 53a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose AlwaysReturnsLValue = true; 54a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose } 55bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose 56bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 57bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose 58bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose ExplodedNodeSet Dst; 59bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose Bldr.takeNodes(Pred); 60bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose 61bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose SVal V = Call.getArgSVal(0); 62bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose 63a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose // If the value being copied is not unknown, load from its location to get 64a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose // an aggregate rvalue. 65dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie if (Optional<Loc> L = V.getAs<Loc>()) 66bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose V = Pred->getState()->getSVal(*L); 67a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose else 68a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose assert(V.isUnknown()); 69bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose 70a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose const Expr *CallExpr = Call.getOriginExpr(); 71a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose evalBind(Dst, CallExpr, Pred, ThisVal, V, true); 72bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose 73a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose PostStmt PS(CallExpr, LCtx); 74bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose for (ExplodedNodeSet::iterator I = Dst.begin(), E = Dst.end(); 75bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose I != E; ++I) { 76bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose ProgramStateRef State = (*I)->getState(); 77a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose if (AlwaysReturnsLValue) 78a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose State = State->BindExpr(CallExpr, LCtx, ThisVal); 79a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose else 80a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose State = bindReturnValue(Call, LCtx, State); 81bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose Bldr.generateNode(PS, State, *I); 82bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose } 83bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose} 84bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose 85ecee1651c100342366a9417c85c6e50399039930Jordan Rose 86ecee1651c100342366a9417c85c6e50399039930Jordan Rose/// Returns a region representing the first element of a (possibly 87ecee1651c100342366a9417c85c6e50399039930Jordan Rose/// multi-dimensional) array. 88ecee1651c100342366a9417c85c6e50399039930Jordan Rose/// 89ecee1651c100342366a9417c85c6e50399039930Jordan Rose/// On return, \p Ty will be set to the base type of the array. 90ecee1651c100342366a9417c85c6e50399039930Jordan Rose/// 91ecee1651c100342366a9417c85c6e50399039930Jordan Rose/// If the type is not an array type at all, the original value is returned. 92ecee1651c100342366a9417c85c6e50399039930Jordan Rosestatic SVal makeZeroElementRegion(ProgramStateRef State, SVal LValue, 93ecee1651c100342366a9417c85c6e50399039930Jordan Rose QualType &Ty) { 94ecee1651c100342366a9417c85c6e50399039930Jordan Rose SValBuilder &SVB = State->getStateManager().getSValBuilder(); 95ecee1651c100342366a9417c85c6e50399039930Jordan Rose ASTContext &Ctx = SVB.getContext(); 96ecee1651c100342366a9417c85c6e50399039930Jordan Rose 97ecee1651c100342366a9417c85c6e50399039930Jordan Rose while (const ArrayType *AT = Ctx.getAsArrayType(Ty)) { 98ecee1651c100342366a9417c85c6e50399039930Jordan Rose Ty = AT->getElementType(); 99ecee1651c100342366a9417c85c6e50399039930Jordan Rose LValue = State->getLValue(Ty, SVB.makeZeroArrayIndex(), LValue); 100ecee1651c100342366a9417c85c6e50399039930Jordan Rose } 101ecee1651c100342366a9417c85c6e50399039930Jordan Rose 102ecee1651c100342366a9417c85c6e50399039930Jordan Rose return LValue; 103ecee1651c100342366a9417c85c6e50399039930Jordan Rose} 104ecee1651c100342366a9417c85c6e50399039930Jordan Rose 105362a31cacc19764f3630928a9e4779af2576e074Jordan Rosevoid ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE, 1065fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek ExplodedNode *Pred, 1075fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek ExplodedNodeSet &destNodes) { 108888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 109075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose ProgramStateRef State = Pred->getState(); 110075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose 111888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const MemRegion *Target = 0; 112ecee1651c100342366a9417c85c6e50399039930Jordan Rose 113ecee1651c100342366a9417c85c6e50399039930Jordan Rose // FIXME: Handle arrays, which run the same constructor for every element. 114ecee1651c100342366a9417c85c6e50399039930Jordan Rose // For now, we just run the first constructor (which should still invalidate 115ecee1651c100342366a9417c85c6e50399039930Jordan Rose // the entire array). 116888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 117888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose switch (CE->getConstructionKind()) { 118888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose case CXXConstructExpr::CK_Complete: { 119075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose // See if we're constructing an existing region by looking at the next 120075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose // element in the CFG. 12166c486f275531df6362b3511fc3af6563561801bTed Kremenek const CFGBlock *B = currBldrCtx->getBlock(); 12266c486f275531df6362b3511fc3af6563561801bTed Kremenek if (currStmtIdx + 1 < B->size()) { 12366c486f275531df6362b3511fc3af6563561801bTed Kremenek CFGElement Next = (*B)[currStmtIdx+1]; 124075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose 125075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose // Is this a constructor for a local variable? 126b07805485c603be3d8011f72611465324c9e664bDavid Blaikie if (Optional<CFGStmt> StmtElem = Next.getAs<CFGStmt>()) { 127b07805485c603be3d8011f72611465324c9e664bDavid Blaikie if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) { 128e460c46c5d602f65354cab0879c458890273591cJordan Rose if (const VarDecl *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) { 129e460c46c5d602f65354cab0879c458890273591cJordan Rose if (Var->getInit()->IgnoreImplicit() == CE) { 130ecee1651c100342366a9417c85c6e50399039930Jordan Rose SVal LValue = State->getLValue(Var, LCtx); 131e460c46c5d602f65354cab0879c458890273591cJordan Rose QualType Ty = Var->getType(); 132ecee1651c100342366a9417c85c6e50399039930Jordan Rose LValue = makeZeroElementRegion(State, LValue, Ty); 133ecee1651c100342366a9417c85c6e50399039930Jordan Rose Target = LValue.getAsRegion(); 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 149ecee1651c100342366a9417c85c6e50399039930Jordan Rose const ValueDecl *Field; 150ecee1651c100342366a9417c85c6e50399039930Jordan Rose SVal FieldVal; 1513a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose if (Init->isIndirectMemberInitializer()) { 152ecee1651c100342366a9417c85c6e50399039930Jordan Rose Field = Init->getIndirectMember(); 153ecee1651c100342366a9417c85c6e50399039930Jordan Rose FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal); 1543a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose } else { 155ecee1651c100342366a9417c85c6e50399039930Jordan Rose Field = Init->getMember(); 156ecee1651c100342366a9417c85c6e50399039930Jordan Rose FieldVal = State->getLValue(Init->getMember(), ThisVal); 1573a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose } 158ecee1651c100342366a9417c85c6e50399039930Jordan Rose 159ecee1651c100342366a9417c85c6e50399039930Jordan Rose QualType Ty = Field->getType(); 160ecee1651c100342366a9417c85c6e50399039930Jordan Rose FieldVal = makeZeroElementRegion(State, FieldVal, Ty); 161ecee1651c100342366a9417c85c6e50399039930Jordan Rose Target = FieldVal.getAsRegion(); 1623a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose } 1633a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 164075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose // FIXME: This will eventually need to handle new-expressions as well. 165be35df19cf9540c03048942ecafc6811643073ecJordan Rose // Don't forget to update the pre-constructor initialization code below. 166075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose } 167075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose 168c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose // If we couldn't find an existing region to construct into, assume we're 169c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose // constructing a temporary. 170c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose if (!Target) { 171c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose MemRegionManager &MRMgr = getSValBuilder().getRegionManager(); 172c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose Target = MRMgr.getCXXTempObjectRegion(CE, LCtx); 173c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose } 174075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose 175888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose break; 176888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose } 177888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose case CXXConstructExpr::CK_VirtualBase: 1781fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose // Make sure we are not calling virtual base class initializers twice. 1791fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose // Only the most-derived object should initialize virtual base classes. 1801fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose if (const Stmt *Outer = LCtx->getCurrentStackFrame()->getCallSite()) { 1811fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose const CXXConstructExpr *OuterCtor = dyn_cast<CXXConstructExpr>(Outer); 1821fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose if (OuterCtor) { 1831fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose switch (OuterCtor->getConstructionKind()) { 1841fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose case CXXConstructExpr::CK_NonVirtualBase: 1851fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose case CXXConstructExpr::CK_VirtualBase: 1861fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose // Bail out! 1871fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose destNodes.Add(Pred); 1881fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose return; 1891fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose case CXXConstructExpr::CK_Complete: 1901fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose case CXXConstructExpr::CK_Delegating: 1911fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose break; 1921fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose } 1931fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose } 1941fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose } 1951fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose // FALLTHROUGH 1961fc9111d85c3929018cd5c85dd14f3dbb5d23d68Jordan Rose case CXXConstructExpr::CK_NonVirtualBase: 197888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose case CXXConstructExpr::CK_Delegating: { 198888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl()); 199888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor, 200888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose LCtx->getCurrentStackFrame()); 201075f6fbcb4d858c09e9b138f8dc10d8d3d43d935Jordan Rose SVal ThisVal = State->getSVal(ThisPtr); 202888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 203888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose if (CE->getConstructionKind() == CXXConstructExpr::CK_Delegating) { 204888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose Target = ThisVal.getAsRegion(); 205888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose } else { 206888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose // Cast to the base type. 2074411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose bool IsVirtual = 2084411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose (CE->getConstructionKind() == CXXConstructExpr::CK_VirtualBase); 2094411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, CE->getType(), 2104411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose IsVirtual); 211e460c46c5d602f65354cab0879c458890273591cJordan Rose Target = BaseVal.getAsRegion(); 212888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose } 213888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose break; 214888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose } 215888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose } 216888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 217d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CallEventManager &CEMgr = getStateManager().getCallEventManager(); 218d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CallEventRef<CXXConstructorCall> Call = 219d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CEMgr.getCXXConstructorCall(CE, Target, State, LCtx); 220cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 221362a31cacc19764f3630928a9e4779af2576e074Jordan Rose ExplodedNodeSet DstPreVisit; 222362a31cacc19764f3630928a9e4779af2576e074Jordan Rose getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this); 223be35df19cf9540c03048942ecafc6811643073ecJordan Rose 224be35df19cf9540c03048942ecafc6811643073ecJordan Rose ExplodedNodeSet PreInitialized; 225be35df19cf9540c03048942ecafc6811643073ecJordan Rose { 226be35df19cf9540c03048942ecafc6811643073ecJordan Rose StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx); 227be35df19cf9540c03048942ecafc6811643073ecJordan Rose if (CE->requiresZeroInitialization()) { 228be35df19cf9540c03048942ecafc6811643073ecJordan Rose // Type of the zero doesn't matter. 229be35df19cf9540c03048942ecafc6811643073ecJordan Rose SVal ZeroVal = svalBuilder.makeZeroVal(getContext().CharTy); 230be35df19cf9540c03048942ecafc6811643073ecJordan Rose 231be35df19cf9540c03048942ecafc6811643073ecJordan Rose for (ExplodedNodeSet::iterator I = DstPreVisit.begin(), 232be35df19cf9540c03048942ecafc6811643073ecJordan Rose E = DstPreVisit.end(); 233be35df19cf9540c03048942ecafc6811643073ecJordan Rose I != E; ++I) { 234be35df19cf9540c03048942ecafc6811643073ecJordan Rose ProgramStateRef State = (*I)->getState(); 235be35df19cf9540c03048942ecafc6811643073ecJordan Rose // FIXME: Once we properly handle constructors in new-expressions, we'll 236be35df19cf9540c03048942ecafc6811643073ecJordan Rose // need to invalidate the region before setting a default value, to make 237be35df19cf9540c03048942ecafc6811643073ecJordan Rose // sure there aren't any lingering bindings around. This probably needs 238be35df19cf9540c03048942ecafc6811643073ecJordan Rose // to happen regardless of whether or not the object is zero-initialized 239be35df19cf9540c03048942ecafc6811643073ecJordan Rose // to handle random fields of a placement-initialized object picking up 240be35df19cf9540c03048942ecafc6811643073ecJordan Rose // old bindings. We might only want to do it when we need to, though. 241be35df19cf9540c03048942ecafc6811643073ecJordan Rose // FIXME: This isn't actually correct for arrays -- we need to zero- 242be35df19cf9540c03048942ecafc6811643073ecJordan Rose // initialize the entire array, not just the first element -- but our 243be35df19cf9540c03048942ecafc6811643073ecJordan Rose // handling of arrays everywhere else is weak as well, so this shouldn't 244be35df19cf9540c03048942ecafc6811643073ecJordan Rose // actually make things worse. Placement new makes this tricky as well, 245be35df19cf9540c03048942ecafc6811643073ecJordan Rose // since it's then possible to be initializing one part of a multi- 246be35df19cf9540c03048942ecafc6811643073ecJordan Rose // dimensional array. 247be35df19cf9540c03048942ecafc6811643073ecJordan Rose State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal); 248be35df19cf9540c03048942ecafc6811643073ecJordan Rose Bldr.generateNode(CE, *I, State, /*tag=*/0, ProgramPoint::PreStmtKind); 249be35df19cf9540c03048942ecafc6811643073ecJordan Rose } 250be35df19cf9540c03048942ecafc6811643073ecJordan Rose } 251be35df19cf9540c03048942ecafc6811643073ecJordan Rose } 252be35df19cf9540c03048942ecafc6811643073ecJordan Rose 25396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose ExplodedNodeSet DstPreCall; 254be35df19cf9540c03048942ecafc6811643073ecJordan Rose getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized, 255d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose *Call, *this); 2565fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 257bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose ExplodedNodeSet DstEvaluated; 258bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx); 259bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose 260053c88bd93e6b2f4e498fd835155f955127d3489Jordan Rose bool IsArray = isa<ElementRegion>(Target); 261053c88bd93e6b2f4e498fd835155f955127d3489Jordan Rose if (CE->getConstructor()->isTrivial() && 262053c88bd93e6b2f4e498fd835155f955127d3489Jordan Rose CE->getConstructor()->isCopyOrMoveConstructor() && 263053c88bd93e6b2f4e498fd835155f955127d3489Jordan Rose !IsArray) { 264053c88bd93e6b2f4e498fd835155f955127d3489Jordan Rose // FIXME: Handle other kinds of trivial constructors as well. 265053c88bd93e6b2f4e498fd835155f955127d3489Jordan Rose for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 266053c88bd93e6b2f4e498fd835155f955127d3489Jordan Rose I != E; ++I) 267053c88bd93e6b2f4e498fd835155f955127d3489Jordan Rose performTrivialCopy(Bldr, *I, *Call); 268053c88bd93e6b2f4e498fd835155f955127d3489Jordan Rose 269bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose } else { 270bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 271bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose I != E; ++I) 272bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose defaultEvalCall(Bldr, *I, *Call); 273bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose } 2745fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 27596479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose ExplodedNodeSet DstPostCall; 276bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated, 277d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose *Call, *this); 27896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this); 279cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu} 280cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 281888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rosevoid ExprEngine::VisitCXXDestructor(QualType ObjectType, 282888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const MemRegion *Dest, 283888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const Stmt *S, 284200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose bool IsBaseDtor, 285888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose ExplodedNode *Pred, 286888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose ExplodedNodeSet &Dst) { 287d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 288d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose ProgramStateRef State = Pred->getState(); 289d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose 290e460c46c5d602f65354cab0879c458890273591cJordan Rose // FIXME: We need to run the same destructor on every element of the array. 291e460c46c5d602f65354cab0879c458890273591cJordan Rose // This workaround will just run the first destructor (which will still 292e460c46c5d602f65354cab0879c458890273591cJordan Rose // invalidate the entire array). 293ecee1651c100342366a9417c85c6e50399039930Jordan Rose SVal DestVal = loc::MemRegionVal(Dest); 294ecee1651c100342366a9417c85c6e50399039930Jordan Rose DestVal = makeZeroElementRegion(State, DestVal, ObjectType); 295ecee1651c100342366a9417c85c6e50399039930Jordan Rose Dest = DestVal.getAsRegion(); 296e460c46c5d602f65354cab0879c458890273591cJordan Rose 297888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl(); 298888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose assert(RecordDecl && "Only CXXRecordDecls should have destructors"); 299888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor(); 300888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 301d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CallEventManager &CEMgr = getStateManager().getCallEventManager(); 302d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CallEventRef<CXXDestructorCall> Call = 303200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose CEMgr.getCXXDestructorCall(DtorDecl, S, Dest, IsBaseDtor, State, LCtx); 304b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek 305563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 306563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose Call->getSourceRange().getBegin(), 307563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose "Error evaluating destructor"); 308563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose 3098d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose ExplodedNodeSet DstPreCall; 3108d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, 311d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose *Call, *this); 312b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu 3138d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose ExplodedNodeSet DstInvalidated; 31466c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx); 3158d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 3168d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose I != E; ++I) 317d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose defaultEvalCall(Bldr, *I, *Call); 3188d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose 3198d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose ExplodedNodeSet DstPostCall; 3208d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated, 321d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose *Call, *this); 322b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu} 323b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu 324d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 325cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu ExplodedNodeSet &Dst) { 32670cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // FIXME: Much of this should eventually migrate to CXXAllocatorCall. 32770cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // Also, we need to decide how allocators actually work -- they're not 32870cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // really part of the CXXNewExpr because they happen BEFORE the 32970cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // CXXConstructExpr subexpression. See PR12014 for some discussion. 33041c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek 33166c486f275531df6362b3511fc3af6563561801bTed Kremenek unsigned blockCount = currBldrCtx->blockCount(); 3323133f79cf451e6302dd05262b4bb53a3e4fd6300Ted Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 333697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev DefinedOrUnknownSVal symVal = UnknownVal(); 334697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev FunctionDecl *FD = CNE->getOperatorNew(); 335697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev 336697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev bool IsStandardGlobalOpNewFunction = false; 337697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev if (FD && !isa<CXXMethodDecl>(FD) && !FD->isVariadic()) { 338697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev if (FD->getNumParams() == 2) { 339697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev QualType T = FD->getParamDecl(1)->getType(); 340697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev if (const IdentifierInfo *II = T.getBaseTypeIdentifier()) 341697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev // NoThrow placement new behaves as a standard new. 342697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev IsStandardGlobalOpNewFunction = II->getName().equals("nothrow_t"); 343697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev } 344697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev else 345697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev // Placement forms are considered non-standard. 346697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev IsStandardGlobalOpNewFunction = (FD->getNumParams() == 1); 347697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev } 348697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev 349697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev // We assume all standard global 'operator new' functions allocate memory in 350697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev // heap. We realize this is an approximation that might not correctly model 351697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev // a custom global allocator. 352697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev if (IsStandardGlobalOpNewFunction) 353697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev symVal = svalBuilder.getConjuredHeapSymbolVal(CNE, LCtx, blockCount); 354697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev else 355697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev symVal = svalBuilder.conjureSymbolVal(0, CNE, LCtx, CNE->getType(), 356697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev blockCount); 35741c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek 358697462881c4b9b704c7859f4bab0a6116c684bb1Anton Yartsev ProgramStateRef State = Pred->getState(); 359d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CallEventManager &CEMgr = getStateManager().getCallEventManager(); 360d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CallEventRef<CXXAllocatorCall> Call = 361d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose CEMgr.getCXXAllocatorCall(CNE, State, LCtx); 362d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose 36370cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // Invalidate placement args. 364d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose // FIXME: Once we figure out how we want allocators to work, 365d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose // we should be using the usual pre-/(default-)eval-/post-call checks here. 366d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose State = Call->invalidateRegions(blockCount); 36776f7761daee0fafd7609b25c95af4e011c743873Jordan Rose if (!State) 36876f7761daee0fafd7609b25c95af4e011c743873Jordan Rose return; 36970cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose 370b59b580a57a36df9d146473098d14c64508ff319Jordan Rose // If we're compiling with exceptions enabled, and this allocation function 371b59b580a57a36df9d146473098d14c64508ff319Jordan Rose // is not declared as non-throwing, failures /must/ be signalled by 372b59b580a57a36df9d146473098d14c64508ff319Jordan Rose // exceptions, and thus the return value will never be NULL. 373b59b580a57a36df9d146473098d14c64508ff319Jordan Rose // C++11 [basic.stc.dynamic.allocation]p3. 374b59b580a57a36df9d146473098d14c64508ff319Jordan Rose if (FD && getContext().getLangOpts().CXXExceptions) { 375b59b580a57a36df9d146473098d14c64508ff319Jordan Rose QualType Ty = FD->getType(); 376b59b580a57a36df9d146473098d14c64508ff319Jordan Rose if (const FunctionProtoType *ProtoType = Ty->getAs<FunctionProtoType>()) 377b59b580a57a36df9d146473098d14c64508ff319Jordan Rose if (!ProtoType->isNothrow(getContext())) 378b59b580a57a36df9d146473098d14c64508ff319Jordan Rose State = State->assume(symVal, true); 379b59b580a57a36df9d146473098d14c64508ff319Jordan Rose } 380b59b580a57a36df9d146473098d14c64508ff319Jordan Rose 38176f7761daee0fafd7609b25c95af4e011c743873Jordan Rose StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 38276f7761daee0fafd7609b25c95af4e011c743873Jordan Rose 38341c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek if (CNE->isArray()) { 38441c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek // FIXME: allocating an array requires simulating the constructors. 38541c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek // For now, just return a symbolicated region. 3865251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie const MemRegion *NewReg = symVal.castAs<loc::MemRegionVal>().getRegion(); 38770cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType(); 38870cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose const ElementRegion *EleReg = 38970cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose getStoreManager().GetElementZeroRegion(NewReg, ObjTy); 390e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose State = State->BindExpr(CNE, Pred->getLocationContext(), 3915eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek loc::MemRegionVal(EleReg)); 392e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose Bldr.generateNode(CNE, Pred, State); 39341c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek return; 39441c5f498b2d10fab683f1c5685ff79c90a737d24Ted Kremenek } 395cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 39670cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // FIXME: Once we have proper support for CXXConstructExprs inside 39770cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // CXXNewExpr, we need to make sure that the constructed object is not 39870cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // immediately invalidated here. (The placement call should happen before 39970cbf3cc09eb21db1108396d30a414ea66d842ccJordan Rose // the constructor call anyway.) 40076f7761daee0fafd7609b25c95af4e011c743873Jordan Rose SVal Result = symVal; 401e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose if (FD && FD->isReservedGlobalPlacementOperator()) { 402e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose // Non-array placement new should always return the placement location. 403e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx); 40476f7761daee0fafd7609b25c95af4e011c743873Jordan Rose Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(), 40576f7761daee0fafd7609b25c95af4e011c743873Jordan Rose CNE->getPlacementArg(0)->getType()); 406e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose } 407e38c1c2c449529e60f48e740cb8662e68e5a5330Jordan Rose 40876f7761daee0fafd7609b25c95af4e011c743873Jordan Rose // Bind the address of the object, then check to see if we cached out. 40976f7761daee0fafd7609b25c95af4e011c743873Jordan Rose State = State->BindExpr(CNE, LCtx, Result); 410e6f2bf86288bc45060b21c4f55a6153b8ba80443Jordan Rose ExplodedNode *NewN = Bldr.generateNode(CNE, Pred, State); 411e6f2bf86288bc45060b21c4f55a6153b8ba80443Jordan Rose if (!NewN) 412e6f2bf86288bc45060b21c4f55a6153b8ba80443Jordan Rose return; 413b061720ddf88b4a1934dbbb1b874a424716cd7d7Jordan Rose 41489e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose // If the type is not a record, we won't have a CXXConstructExpr as an 41589e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose // initializer. Copy the value over. 41689e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose if (const Expr *Init = CNE->getInitializer()) { 41789e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose if (!isa<CXXConstructExpr>(Init)) { 418b061720ddf88b4a1934dbbb1b874a424716cd7d7Jordan Rose assert(Bldr.getResults().size() == 1); 419e6f2bf86288bc45060b21c4f55a6153b8ba80443Jordan Rose Bldr.takeNodes(NewN); 42076f7761daee0fafd7609b25c95af4e011c743873Jordan Rose evalBind(Dst, CNE, NewN, Result, State->getSVal(Init, LCtx), 42176f7761daee0fafd7609b25c95af4e011c743873Jordan Rose /*FirstInit=*/IsStandardGlobalOpNewFunction); 42289e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose } 42389e5aaf57e20b39e35b0d068ebbc09ae736f2e1eJordan Rose } 424cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu} 425cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 426d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, 427ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNode *Pred, ExplodedNodeSet &Dst) { 42866c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 4294fafeb6452a79794726a1adc53fb5e2a5887c5f9Erik Verbruggen ProgramStateRef state = Pred->getState(); 4304fafeb6452a79794726a1adc53fb5e2a5887c5f9Erik Verbruggen Bldr.generateNode(CDE, Pred, state); 4316b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu} 432cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 433337e4dbc6859589b8878146a88bebf754e916702Ted Kremenekvoid ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS, 434337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek ExplodedNode *Pred, 435337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek ExplodedNodeSet &Dst) { 436337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek const VarDecl *VD = CS->getExceptionDecl(); 437ce612f5a7d306f919c7ae57fcd8c5ecb5d83d54eTed Kremenek if (!VD) { 438ce612f5a7d306f919c7ae57fcd8c5ecb5d83d54eTed Kremenek Dst.Add(Pred); 439ce612f5a7d306f919c7ae57fcd8c5ecb5d83d54eTed Kremenek return; 440ce612f5a7d306f919c7ae57fcd8c5ecb5d83d54eTed Kremenek } 441ce612f5a7d306f919c7ae57fcd8c5ecb5d83d54eTed Kremenek 442337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 4433b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(), 44466c486f275531df6362b3511fc3af6563561801bTed Kremenek currBldrCtx->blockCount()); 445337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek ProgramStateRef state = Pred->getState(); 446337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek state = state->bindLoc(state->getLValue(VD, LCtx), V); 447337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek 44866c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 449337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek Bldr.generateNode(CS, Pred, state); 450337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek} 451337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek 452d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 4536b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu ExplodedNodeSet &Dst) { 45466c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 455ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 456cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu // Get the this object region from StoreManager. 4575eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 458cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu const MemRegion *R = 459c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek svalBuilder.getRegionManager().getCXXThisRegion( 460cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu getContext().getCanonicalType(TE->getType()), 4615eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek LCtx); 462cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu 4638bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 464cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu SVal V = state->getSVal(loc::MemRegionVal(R)); 4655eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V)); 466cb7464ab402d057849dda9749d62a62d86c35ab8Zhongxing Xu} 467