aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2024-09-18 15:44:31 -0400
committerMarek Polacek <polacek@redhat.com>2024-09-30 15:20:31 -0400
commit4bcfaaed25b1b8ecc81f6a28d9ca76f00870dedf (patch)
treebab5c07fc8397dd14661f2e4ac5c72b6ab7b8997 /gcc
parent65073a5b90c00a1c47efae8a67b9c754e2287ee0 (diff)
downloadgcc-4bcfaaed25b1b8ecc81f6a28d9ca76f00870dedf.zip
gcc-4bcfaaed25b1b8ecc81f6a28d9ca76f00870dedf.tar.gz
gcc-4bcfaaed25b1b8ecc81f6a28d9ca76f00870dedf.tar.bz2
c++: concept in default argument [PR109859]
1) We're hitting the assert in cp_parser_placeholder_type_specifier. It says that if it turns out to be false, we should do error() instead. Do so, then. 2) lambda-targ8.C should compile fine, though. The problem was that local_variables_forbidden_p wasn't cleared when we're about to parse the optional template-parameter-list for a lambda in a default argument. PR c++/109859 gcc/cp/ChangeLog: * parser.cc (cp_parser_lambda_declarator_opt): Temporarily clear local_variables_forbidden_p. (cp_parser_placeholder_type_specifier): Turn an assert into an error. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-defarg3.C: New test. * g++.dg/cpp2a/lambda-targ8.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/parser.cc9
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-defarg3.C8
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/lambda-targ8.C10
3 files changed, 25 insertions, 2 deletions
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index f50534f..0944827 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -11891,6 +11891,11 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
"lambda templates are only available with "
"%<-std=c++20%> or %<-std=gnu++20%>");
+ /* Even though the whole lambda may be a default argument, its
+ template-parameter-list is a context where it's OK to create
+ new parameters. */
+ auto lvf = make_temp_override (parser->local_variables_forbidden_p, 0u);
+
cp_lexer_consume_token (parser->lexer);
template_param_list = cp_parser_template_parameter_list (parser);
@@ -20989,8 +20994,8 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc,
/* In a default argument we may not be creating new parameters. */
if (parser->local_variables_forbidden_p & LOCAL_VARS_FORBIDDEN)
{
- /* If this assert turns out to be false, do error() instead. */
- gcc_assert (tentative);
+ if (!tentative)
+ error_at (loc, "invalid use of concept-name %qD", con);
return error_mark_node;
}
return build_constrained_parameter (con, proto, args);
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-defarg3.C b/gcc/testsuite/g++.dg/cpp2a/concepts-defarg3.C
new file mode 100644
index 0000000..6fe82f9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-defarg3.C
@@ -0,0 +1,8 @@
+// PR c++/109859
+// { dg-do compile { target c++20 } }
+
+template<class>
+concept C = true;
+
+template <class = C> // { dg-error "invalid use of concept-name .C." }
+int f();
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-targ8.C b/gcc/testsuite/g++.dg/cpp2a/lambda-targ8.C
new file mode 100644
index 0000000..3685b0e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/lambda-targ8.C
@@ -0,0 +1,10 @@
+// PR c++/109859
+// { dg-do compile { target c++20 } }
+
+template<typename>
+concept A = true;
+
+template<auto = []<A a> {}>
+int x;
+
+void g() { (void) x<>; }