r181669 - C++1y: provide full 'auto' return type deduction for lambda expressions. This

Richard Smith richard-llvm at metafoo.co.uk
Sat May 11 20:09:36 PDT 2013


Author: rsmith
Date: Sat May 11 22:09:35 2013
New Revision: 181669

URL: http://llvm.org/viewvc/llvm-project?rev=181669&view=rev
Log:
C++1y: provide full 'auto' return type deduction for lambda expressions. This
completes the implementation of N3638.

Added:
    cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p12-1y.cpp
    cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4-1y.cpp
Modified:
    cfe/trunk/docs/LanguageExtensions.rst
    cfe/trunk/lib/Lex/PPMacroExpansion.cpp
    cfe/trunk/lib/Sema/SemaStmt.cpp
    cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp
    cfe/trunk/test/Lexer/has_feature_cxx0x.cpp
    cfe/trunk/www/cxx_status.html

Modified: cfe/trunk/docs/LanguageExtensions.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=181669&r1=181668&r2=181669&view=diff
==============================================================================
--- cfe/trunk/docs/LanguageExtensions.rst (original)
+++ cfe/trunk/docs/LanguageExtensions.rst Sat May 11 22:09:35 2013
@@ -852,7 +852,6 @@ Use ``__has_feature(cxx_return_type_dedu
 ``__has_extension(cxx_return_type_deduction)`` to determine if support
 for return type deduction for functions (using ``auto`` as a return type)
 is enabled.
-Clang's implementation of this feature is incomplete.
 
 C++1y runtime-sized arrays
 ^^^^^^^^^^^^^^^^^^^^^^^^^^

Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=181669&r1=181668&r2=181669&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Sat May 11 22:09:35 2013
@@ -798,7 +798,7 @@ static bool HasFeature(const Preprocesso
            //.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)

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=181669&r1=181668&r2=181669&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Sat May 11 22:09:35 2013
@@ -2362,22 +2362,37 @@ Sema::PerformMoveOrCopyInitialization(co
 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 Ret
   if (RetValExp && DiagnoseUnexpandedParameterPack(RetValExp))
     return StmtError();
 
-  // FIXME: Unify this and C++1y auto function handling.
   if (isa<CapturingScopeInfo>(getCurFunction()))
     return ActOnCapScopeReturnStmt(ReturnLoc, RetValExp);
 

Added: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p12-1y.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p12-1y.cpp?rev=181669&view=auto
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p12-1y.cpp (added)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p12-1y.cpp Sat May 11 22:09:35 2013
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+// RUN: %clang_cc1 -std=c++1y -verify %s
+
+template<typename T> struct S { typedef int type; };
+
+template<typename T> void f() {
+  auto x = [] { return 0; } ();
+  // FIXME: We should be able to produce a 'missing typename' diagnostic here.
+  S<decltype(x)>::type n; // expected-error 2{{}}
+}
+
+#if __cplusplus > 201103L
+template<typename T> void g() {
+  auto x = [] () -> auto { return 0; } ();
+  S<decltype(x)>::type n; // expected-error 2{{}}
+}
+#endif

Added: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4-1y.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4-1y.cpp?rev=181669&view=auto
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4-1y.cpp (added)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4-1y.cpp Sat May 11 22:09:35 2013
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++1y %s -verify
+
+int a;
+int &b = [] (int &r) -> decltype(auto) { return r; } (a);
+int &c = [] (int &r) -> decltype(auto) { return (r); } (a);
+int &d = [] (int &r) -> auto & { return r; } (a);
+int &e = [] (int &r) -> auto { return r; } (a); // expected-error {{cannot bind to a temporary}}
+int &f = [] (int r) -> decltype(auto) { return r; } (a); // expected-error {{cannot bind to a temporary}}
+int &g = [] (int r) -> decltype(auto) { return (r); } (a); // expected-warning {{reference to stack}}

Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp?rev=181669&r1=181668&r2=181669&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp Sat May 11 22:09:35 2013
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
+// RUN: %clang_cc1 -fsyntax-only -std=c++1y %s -verify
 
 void missing_lambda_declarator() {
   [](){}();

Modified: cfe/trunk/test/Lexer/has_feature_cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/has_feature_cxx0x.cpp?rev=181669&r1=181668&r2=181669&view=diff
==============================================================================
--- cfe/trunk/test/Lexer/has_feature_cxx0x.cpp (original)
+++ cfe/trunk/test/Lexer/has_feature_cxx0x.cpp Sat May 11 22:09:35 2013
@@ -346,3 +346,13 @@ int no_aggregate_nsdmi();
 // CHECK-1Y: has_aggregate_nsdmi
 // CHECK-11: no_aggregate_nsdmi
 // CHECK-NO-11: no_aggregate_nsdmi
+
+#if __has_feature(cxx_return_type_deduction)
+int has_return_type_deduction();
+#else
+int no_return_type_deduction();
+#endif
+
+// CHECK-1Y: has_return_type_deduction
+// CHECK-11: no_return_type_deduction
+// CHECK-NO-11: no_return_type_deduction

Modified: cfe/trunk/www/cxx_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=181669&r1=181668&r2=181669&view=diff
==============================================================================
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Sat May 11 22:09:35 2013
@@ -431,7 +431,7 @@ available.</p>
     </tr>
     <tr>
       <td>Return type deduction for normal functions</td>
-      <td class="partial" align="center">Partial</td>
+      <td class="svn" align="center">SVN</td>
     </tr>
     <tr>
       <td>Runtime-sized arrays with automatic storage duration</td>





More information about the cfe-commits mailing list