summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Lex/PPMacroExpansion.cpp2
-rw-r--r--clang/lib/Sema/SemaStmt.cpp24
2 files changed, 20 insertions, 6 deletions
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 24c6217ced2..3abca1f1498 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -798,7 +798,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
//.Case("cxx_generalized_capture", LangOpts.CPlusPlus1y)
//.Case("cxx_generic_lambda", LangOpts.CPlusPlus1y)
//.Case("cxx_relaxed_constexpr", LangOpts.CPlusPlus1y)
- //.Case("cxx_return_type_deduction", LangOpts.CPlusPlus1y)
+ .Case("cxx_return_type_deduction", LangOpts.CPlusPlus1y)
//.Case("cxx_runtime_array", LangOpts.CPlusPlus1y)
.Case("cxx_aggregate_nsdmi", LangOpts.CPlusPlus1y)
//.Case("cxx_variable_templates", LangOpts.CPlusPlus1y)
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index b5ff7a30a9e..6d568c4d0b0 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -2362,22 +2362,37 @@ Sema::PerformMoveOrCopyInitialization(const InitializedEntity &Entity,
StmtResult
Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
// If this is the first return we've seen, infer the return type.
- // [expr.prim.lambda]p4 in C++11; block literals follow a superset of those
- // rules which allows multiple return statements.
+ // [expr.prim.lambda]p4 in C++11; block literals follow the same rules.
CapturingScopeInfo *CurCap = cast<CapturingScopeInfo>(getCurFunction());
QualType FnRetType = CurCap->ReturnType;
// For blocks/lambdas with implicit return types, we check each return
// statement individually, and deduce the common return type when the block
// or lambda is completed.
- if (CurCap->HasImplicitReturnType) {
+ if (AutoType *AT =
+ FnRetType.isNull() ? 0 : FnRetType->getContainedAutoType()) {
+ // In C++1y, the return type may involve 'auto'.
+ FunctionDecl *FD = cast<LambdaScopeInfo>(CurCap)->CallOperator;
+ if (CurContext->isDependentContext()) {
+ // C++1y [dcl.spec.auto]p12:
+ // Return type deduction [...] occurs when the definition is
+ // instantiated even if the function body contains a return
+ // statement with a non-type-dependent operand.
+ CurCap->ReturnType = FnRetType = Context.DependentTy;
+ } else if (DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) {
+ FD->setInvalidDecl();
+ return StmtError();
+ } else
+ CurCap->ReturnType = FnRetType = FD->getResultType();
+ } else if (CurCap->HasImplicitReturnType) {
+ // FIXME: Fold this into the 'auto' codepath above.
if (RetValExp && !isa<InitListExpr>(RetValExp)) {
ExprResult Result = DefaultFunctionArrayLvalueConversion(RetValExp);
if (Result.isInvalid())
return StmtError();
RetValExp = Result.take();
- if (!RetValExp->isTypeDependent())
+ if (!CurContext->isDependentContext())
FnRetType = RetValExp->getType();
else
FnRetType = CurCap->ReturnType = Context.DependentTy;
@@ -2553,7 +2568,6 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
if (RetValExp && DiagnoseUnexpandedParameterPack(RetValExp))
return StmtError();
- // FIXME: Unify this and C++1y auto function handling.
if (isa<CapturingScopeInfo>(getCurFunction()))
return ActOnCapScopeReturnStmt(ReturnLoc, RetValExp);
OpenPOWER on IntegriCloud