https://gcc.gnu.org/g:4bcfaaed25b1b8ecc81f6a28d9ca76f00870dedf

commit r15-3980-g4bcfaaed25b1b8ecc81f6a28d9ca76f00870dedf
Author: Marek Polacek <pola...@redhat.com>
Date:   Wed Sep 18 15:44:31 2024 -0400

    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 <ja...@redhat.com>

Diff:
---
 gcc/cp/parser.cc                              |  9 +++++++--
 gcc/testsuite/g++.dg/cpp2a/concepts-defarg3.C |  8 ++++++++
 gcc/testsuite/g++.dg/cpp2a/lambda-targ8.C     | 10 ++++++++++
 3 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index f50534f5f395..0944827d777b 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 000000000000..6fe82f91e434
--- /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 000000000000..3685b0ef880b
--- /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<>; }

Reply via email to