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