|
@@ -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:
|