]> granicus.if.org Git - clang/commitdiff
Don't allow deduction of a lambda result type from an initializer
authorDouglas Gregor <dgregor@apple.com>
Thu, 9 Feb 2012 18:40:39 +0000 (18:40 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 9 Feb 2012 18:40:39 +0000 (18:40 +0000)
list; it is not an expression.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150194 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaStmt.cpp
test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp

index aff79a6cda0b210f4c19c23eea69518e3322760d..b018357343b47a253f141967d88617342ad62c51 100644 (file)
@@ -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<DiagGroup<"lambda-return">>;
+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">;
index e49bcfada6573b0232101bbc97ea96047bcf1212..0adfb948009f8de950ead2f356009a39681d5f5f 100644 (file)
@@ -1798,7 +1798,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
   CapturingScopeInfo *CurCap = cast<CapturingScopeInfo>(getCurFunction());
   if (CurCap->HasImplicitReturnType) {
     QualType ReturnT;
-    if (RetValExp) {
+    if (RetValExp && !isa<InitListExpr>(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.
index a3a29c09773d287eff5a18d207572a3484066c77..cff0c0995054a324ed02f58c25a1f8e2565ad7cb 100644 (file)
@@ -17,6 +17,7 @@ void infer_void_return_type(int i) {
     switch (x) {
     case 0: return get<void>();
     case 1: return;
+    case 2: return { 1, 2.0 }; // expected-error{{cannot deduce lambda return type from initializer list}}
     }
   }(7);
 }