From: Jordan Rose Date: Sat, 30 Mar 2013 01:31:48 +0000 (+0000) Subject: [analyzer] Restructure ExprEngine::VisitCXXNewExpr to do a bit less work. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=76f7761daee0fafd7609b25c95af4e011c743873;p=clang [analyzer] Restructure ExprEngine::VisitCXXNewExpr to do a bit less work. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178402 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index 64c361d4d8..b0f2579cd9 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -274,7 +274,6 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, // Also, we need to decide how allocators actually work -- they're not // really part of the CXXNewExpr because they happen BEFORE the // CXXConstructExpr subexpression. See PR12014 for some discussion. - StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); unsigned blockCount = currBldrCtx->blockCount(); const LocationContext *LCtx = Pred->getLocationContext(); @@ -312,6 +311,8 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, // FIXME: Once we figure out how we want allocators to work, // we should be using the usual pre-/(default-)eval-/post-call checks here. State = Call->invalidateRegions(blockCount); + if (!State) + return; // If we're compiling with exceptions enabled, and this allocation function // is not declared as non-throwing, failures /must/ be signalled by @@ -324,6 +325,8 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, State = State->assume(symVal, true); } + StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); + if (CNE->isArray()) { // FIXME: allocating an array requires simulating the constructors. // For now, just return a symbolicated region. @@ -341,16 +344,16 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, // CXXNewExpr, we need to make sure that the constructed object is not // immediately invalidated here. (The placement call should happen before // the constructor call anyway.) + SVal Result = symVal; if (FD && FD->isReservedGlobalPlacementOperator()) { // Non-array placement new should always return the placement location. SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx); - SVal Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(), - CNE->getPlacementArg(0)->getType()); - State = State->BindExpr(CNE, LCtx, Result); - } else { - State = State->BindExpr(CNE, LCtx, symVal); + Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(), + CNE->getPlacementArg(0)->getType()); } + // Bind the address of the object, then check to see if we cached out. + State = State->BindExpr(CNE, LCtx, Result); ExplodedNode *NewN = Bldr.generateNode(CNE, Pred, State); if (!NewN) return; @@ -363,10 +366,8 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, Bldr.takeNodes(NewN); assert(!CNE->getType()->getPointeeCXXRecordDecl()); - - SVal Location = State->getSVal(CNE, LCtx); - bool FirstInit = (Location == symVal); - evalBind(Dst, CNE, TmpN, Location, State->getSVal(Init, LCtx), FirstInit); + evalBind(Dst, CNE, NewN, Result, State->getSVal(Init, LCtx), + /*FirstInit=*/IsStandardGlobalOpNewFunction); } } }