From: Patrick Palka Date: Thu, 15 Dec 2022 21:07:09 +0000 (-0500) Subject: c++: class-scope qualified constrained auto [PR107188] X-Git-Tag: basepoints/gcc-14~2476 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=147e276b580b674a46bc3b9c461ae7837fd48aba;p=thirdparty%2Fgcc.git c++: class-scope qualified constrained auto [PR107188] Here when parsing the class-scope auto constrained by a qualified concept-id, we first tentatively parse the overall member-declaration as a deprecated access-declaration, during which we parse C as a standalone TEMPLATE_ID_EXPR (separate from the auto) and end up emitting the stray error concepts-placeholder11.C:9:6: error: wrong number of template arguments (1, should be 2) 9 | N::C auto f() { return 0; } | ^~~~~~ concepts-placeholder11.C:5:34: note: provided for ‘template concept N::C’ 5 | template concept C = true; | ^ from build_concept_id called from cp_parser_template_id_expr. We could fix this by adding a complain parameter to build_concept_id and passing tf_none when parsing tentatively. However, it seems this can also be fixed in a more general way that might benefit non-concepts code: when tentatively parsing an access-declaration, abort the parse early if the qualifying scope isn't possibly a class or enumeration type, so that we avoid parsing C as a TEMPLATE_ID_EXPR here in the first place. This patch takes this latter approach. PR c++/107188 gcc/cp/ChangeLog: * parser.cc (cp_parser_using_declaration): Give up early if the scope of an access-declaration isn't possibly a class type. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-placeholder11.C: New test. --- diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 8f9f27fad68a..1d59ccd9de83 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -21673,6 +21673,13 @@ cp_parser_using_declaration (cp_parser* parser, cp_warn_deprecated_use_scopes (qscope); + if (access_declaration_p + && !MAYBE_CLASS_TYPE_P (qscope) + && TREE_CODE (qscope) != ENUMERAL_TYPE) + /* If the qualifying scope of an access-declaration isn't a class + or enumeration type then it can't be valid. */ + cp_parser_simulate_error (parser); + if (access_declaration_p && cp_parser_error_occurred (parser)) /* Something has already gone wrong; there's no need to parse further. Since an error has occurred, the return value of diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder11.C b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder11.C new file mode 100644 index 000000000000..61eef743bae8 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder11.C @@ -0,0 +1,10 @@ +// PR c++/107188 +// { dg-do compile { target c++20 } } + +namespace N { + template concept C = true; +} + +struct X { + N::C auto f() { return 0; } +};