From 6b199af2a4e8dbcd65989a636aa9bade239e605f Mon Sep 17 00:00:00 2001
From: Eczbek <[email protected]>
Date: Thu, 23 Oct 2025 21:51:01 -0400
Subject: [PATCH] c++: Allow lambda expressions in template type parameters
 [PR116952]

        PR c++/116952

gcc/cp/ChangeLog:

        * parser.cc (cp_parser_lambda_expression): Remove check for
        lambda expressions in template type parameters.

gcc/testsuite/ChangeLog:

        * g++.dg/cpp2a/lambda-uneval14.C: Revise old test.
        * g++.dg/cpp2a/lambda-uneval29.C: New test.
---
 gcc/cp/parser.cc                             | 21 +++-----------------
 gcc/testsuite/g++.dg/cpp2a/lambda-uneval14.C |  4 ++--
 gcc/testsuite/g++.dg/cpp2a/lambda-uneval29.C |  7 +++++++
 3 files changed, 12 insertions(+), 20 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/lambda-uneval29.C

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 0917a16a908..8a6b5b0e369 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -11895,23 +11895,7 @@ cp_parser_lambda_expression (cp_parser* parser,
   LAMBDA_EXPR_LOCATION (lambda_expr) = token->location;
   LAMBDA_EXPR_CONSTEVAL_BLOCK_P (lambda_expr) = consteval_block_p;

-  if (cxx_dialect >= cxx20)
-    {
- /* C++20 allows lambdas in unevaluated context, but one in the type of a
-        non-type parameter is nonsensical.
-
-        Distinguish a lambda in the parameter type from a lambda in the
-        default argument by looking at local_variables_forbidden_p, which is
-        only set in default arguments.  */
- if (processing_template_parmlist && !parser->local_variables_forbidden_p)
-       {
-         error_at (token->location,
-                   "lambda-expression in template parameter type");
-         token->error_reported = true;
-         ok = false;
-       }
-    }
-  else if (cp_unevaluated_operand)
+  if (cxx_dialect < cxx20 && cp_unevaluated_operand)
     {
       if (!token->error_reported)
        {
@@ -11922,7 +11906,8 @@ cp_parser_lambda_expression (cp_parser* parser,
        }
       ok = false;
     }
- else if (parser->in_template_argument_list_p || processing_template_parmlist)
+  else if (cxx_dialect < cxx20
+ && (parser->in_template_argument_list_p || processing_template_parmlist))
     {
       if (!token->error_reported)
        {
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-uneval14.C b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval14.C
index a18035954e1..d0e74e3c805 100644
--- a/gcc/testsuite/g++.dg/cpp2a/lambda-uneval14.C
+++ b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval14.C
@@ -1,6 +1,6 @@
 // PR c++/99478
 // { dg-do compile { target c++20 } }

-template <decltype ([] {})> auto f() {} // { dg-error "lambda" }
+template <decltype ([] {})> auto f() {}

-int main() { f<{}>(); }          // { dg-prune-output "no match" }
+int main() { f<{}>(); }
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-uneval29.C b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval29.C
new file mode 100644
index 00000000000..b396b7313be
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval29.C
@@ -0,0 +1,7 @@
+// PR c++/116952
+// { dg-do compile { target c++20 } }
+
+template<typename, auto> concept A = true;
+template<A<[] {}>> int x;
+
+template<[] {}> int y; // { dg-error "" }
--
2.51.0

Reply via email to