diff options
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 4c98ffed71b..f6faf38c95e 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1798,6 +1798,8 @@ static void CheckPoppedLabel(LabelDecl *L, Sema &S) { } void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { + S->mergeNRVOIntoParent(); + if (S->decl_empty()) return; assert((S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope)) && "Scope shouldn't contain decls!"); @@ -12561,24 +12563,21 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D, /// optimization. /// /// Each of the variables that is subject to the named return value -/// optimization will be marked as NRVO variable candidates in the AST, and any +/// optimization will be marked as NRVO variables in the AST, and any /// return statement that has a marked NRVO variable as its NRVO candidate can /// use the named return value optimization. /// -/// This function applies a very simplistic algorithm for NRVO: if every -/// reachable return statement in the scope of a variable has the same NRVO -/// candidate, that candidate is an NRVO variable. +/// This function applies a very simplistic algorithm for NRVO: if every return +/// statement in the scope of a variable has the same NRVO candidate, that +/// candidate is an NRVO variable. void Sema::computeNRVO(Stmt *Body, FunctionScopeInfo *Scope) { - for (ReturnStmt *Return : Scope->Returns) { - const VarDecl *Candidate = Return->getNRVOCandidate(); - if (!Candidate) - continue; - - if (Candidate->isNRVOCandidate()) - const_cast<VarDecl*>(Candidate)->setNRVOVariable(true); + ReturnStmt **Returns = Scope->Returns.data(); - if (!Candidate->isNRVOVariable()) - Return->setNRVOCandidate(nullptr); + for (unsigned I = 0, E = Scope->Returns.size(); I != E; ++I) { + if (const VarDecl *NRVOCandidate = Returns[I]->getNRVOCandidate()) { + if (!NRVOCandidate->isNRVOVariable()) + Returns[I]->setNRVOCandidate(nullptr); + } } } @@ -12713,8 +12712,12 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(FD)) MarkVTableUsed(FD->getLocation(), Destructor->getParent()); - // Try to apply the named return value optimization. - computeNRVO(Body, getCurFunction()); + // Try to apply the named return value optimization. We have to check + // if we can do this here because lambdas keep return statements around + // to deduce an implicit return type. + if (FD->getReturnType()->isRecordType() && + (!getLangOpts().CPlusPlus || !FD->isDependentContext())) + computeNRVO(Body, getCurFunction()); } // GNU warning -Wmissing-prototypes: |