From: Douglas Gregor Date: Thu, 9 Feb 2012 18:40:39 +0000 (+0000) Subject: Don't allow deduction of a lambda result type from an initializer X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a0c2b21e0d84ad289781e08e14148da6b8b8b76d;p=clang Don't allow deduction of a lambda result type from an initializer list; it is not an expression. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150194 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index aff79a6cda..b018357343 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -4130,6 +4130,8 @@ def ext_lambda_implies_void_return : ExtWarn< "C++11 requires lambda with omitted result type to consist of a single " "return statement">, InGroup>; +def err_lambda_return_init_list : Error< + "cannot deduce lambda return type from initializer list">; def err_operator_arrow_circular : Error< "circular pointer delegation detected">; diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index e49bcfada6..0adfb94800 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -1798,7 +1798,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { CapturingScopeInfo *CurCap = cast(getCurFunction()); if (CurCap->HasImplicitReturnType) { QualType ReturnT; - if (RetValExp) { + if (RetValExp && !isa(RetValExp)) { ExprResult Result = DefaultFunctionArrayLvalueConversion(RetValExp); if (Result.isInvalid()) return StmtError(); @@ -1808,7 +1808,15 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { ReturnT = RetValExp->getType(); else ReturnT = Context.DependentTy; - } else { + } else { + if (RetValExp) { + // C++11 [expr.lambda.prim]p4 bans inferring the result from an + // initializer list, because it is not an expression (even + // though we represent it as one). We still deduce 'void'. + Diag(ReturnLoc, diag::err_lambda_return_init_list) + << RetValExp->getSourceRange(); + } + ReturnT = Context.VoidTy; } // We require the return types to strictly match here. diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp index a3a29c0977..cff0c09950 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp @@ -17,6 +17,7 @@ void infer_void_return_type(int i) { switch (x) { case 0: return get(); case 1: return; + case 2: return { 1, 2.0 }; // expected-error{{cannot deduce lambda return type from initializer list}} } }(7); }