On 11/25/25 10:56 AM, Eczbek wrote:
 From 68ef8820621906101d18d20a98c4a43bad6770cd Mon Sep 17 00:00:00 2001
From: Eczbek <[email protected]>
Date: Mon, 24 Nov 2025 23:03:51 -0500
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.

Thanks for following up on this! It seemed simpler to me to just revert my r11-8166-ge1666ebd9ad31d change, so I pushed that along with the testsuite changes.

gcc/testsuite/ChangeLog:

     * g++.dg/cpp2a/lambda-uneval14.C: Revise incorrect 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 e0c8e0ec8ad..ddb14fda771 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -11963,23 +11963,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)
      {
@@ -11990,7 +11974,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 "" }

Reply via email to