Message ID | 20240115221448.498382-1-polacek@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: ICE with auto in template arg [PR110065] | expand |
On 1/15/24 17:14, Marek Polacek wrote: > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? OK, thanks. > -- >8 -- > > Here we started crashing with r14-1659 because that removed the > auto checking in cp_parser_template_type_arg which seemed like > dead code. But the attached test shows that the code can still > be reached because cp_parser_type_id_1 checks auto only when > auto_is_implicit_function_template_parm_p is on. > > Then I noticed that we're still crashing in C++20, and that ICE > started with r12-4772. So I changed the reemerged check to use > flag_concepts_ts rather than flag_concepts on the basis that > check_auto_in_tmpl_args also checks flag_concepts_ts. > > PR c++/110065 > > gcc/cp/ChangeLog: > > * parser.cc (cp_parser_template_type_arg): Add auto checking. > > gcc/testsuite/ChangeLog: > > * g++.dg/concepts/auto8.C: New test. > * g++.dg/concepts/auto8a.C: New test. > --- > gcc/cp/parser.cc | 12 ++++++++++-- > gcc/testsuite/g++.dg/concepts/auto8.C | 17 +++++++++++++++++ > gcc/testsuite/g++.dg/concepts/auto8a.C | 18 ++++++++++++++++++ > 3 files changed, 45 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/concepts/auto8.C > create mode 100644 gcc/testsuite/g++.dg/concepts/auto8a.C > > diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc > index 8ab98cc0c23..e92309b8960 100644 > --- a/gcc/cp/parser.cc > +++ b/gcc/cp/parser.cc > @@ -25063,12 +25063,20 @@ cp_parser_type_id (cp_parser *parser, cp_parser_flags flags, > static tree > cp_parser_template_type_arg (cp_parser *parser) > { > - tree r; > const char *saved_message = parser->type_definition_forbidden_message; > parser->type_definition_forbidden_message > = G_("types may not be defined in template arguments"); > - r = cp_parser_type_id_1 (parser, CP_PARSER_FLAGS_NONE, true, false, NULL); > + tree r = cp_parser_type_id_1 (parser, CP_PARSER_FLAGS_NONE, > + /*is_template_arg=*/true, > + /*is_trailing_return=*/false, nullptr); > parser->type_definition_forbidden_message = saved_message; > + /* cp_parser_type_id_1 checks for auto, but only for > + ->auto_is_implicit_function_template_parm_p. */ > + if (cxx_dialect >= cxx14 && !flag_concepts_ts && type_uses_auto (r)) > + { > + error ("invalid use of %<auto%> in template argument"); > + r = error_mark_node; > + } > return r; > } > > diff --git a/gcc/testsuite/g++.dg/concepts/auto8.C b/gcc/testsuite/g++.dg/concepts/auto8.C > new file mode 100644 > index 00000000000..f9d98b2ec0f > --- /dev/null > +++ b/gcc/testsuite/g++.dg/concepts/auto8.C > @@ -0,0 +1,17 @@ > +// PR c++/110065 > +// { dg-do compile { target c++17 } } > + > +template <typename> > +inline constexpr bool t = false; > + > +int > +f () > +{ > + return t<auto(&)(const int*) -> auto&>; // { dg-error "template argument" } > +} > + > +void > +g () > +{ > + t<auto(&)(const int*) -> auto&>; // { dg-error "template argument" } > +} > diff --git a/gcc/testsuite/g++.dg/concepts/auto8a.C b/gcc/testsuite/g++.dg/concepts/auto8a.C > new file mode 100644 > index 00000000000..fc60dc871c2 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/concepts/auto8a.C > @@ -0,0 +1,18 @@ > +// PR c++/110065 > +// { dg-do compile { target c++17 } } > +// { dg-additional-options -fconcepts-ts } > + > +template <typename> > +inline constexpr bool t = false; > + > +int > +f () > +{ > + return t<auto(&)(const int*) -> auto&>; // { dg-error "template argument" } > +} > + > +void > +g () > +{ > + t<auto(&)(const int*) -> auto&>; // { dg-error "template argument" } > +} > > base-commit: 731444b3c39e3dc3dd8778f430a38742861dcca1
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 8ab98cc0c23..e92309b8960 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -25063,12 +25063,20 @@ cp_parser_type_id (cp_parser *parser, cp_parser_flags flags, static tree cp_parser_template_type_arg (cp_parser *parser) { - tree r; const char *saved_message = parser->type_definition_forbidden_message; parser->type_definition_forbidden_message = G_("types may not be defined in template arguments"); - r = cp_parser_type_id_1 (parser, CP_PARSER_FLAGS_NONE, true, false, NULL); + tree r = cp_parser_type_id_1 (parser, CP_PARSER_FLAGS_NONE, + /*is_template_arg=*/true, + /*is_trailing_return=*/false, nullptr); parser->type_definition_forbidden_message = saved_message; + /* cp_parser_type_id_1 checks for auto, but only for + ->auto_is_implicit_function_template_parm_p. */ + if (cxx_dialect >= cxx14 && !flag_concepts_ts && type_uses_auto (r)) + { + error ("invalid use of %<auto%> in template argument"); + r = error_mark_node; + } return r; } diff --git a/gcc/testsuite/g++.dg/concepts/auto8.C b/gcc/testsuite/g++.dg/concepts/auto8.C new file mode 100644 index 00000000000..f9d98b2ec0f --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/auto8.C @@ -0,0 +1,17 @@ +// PR c++/110065 +// { dg-do compile { target c++17 } } + +template <typename> +inline constexpr bool t = false; + +int +f () +{ + return t<auto(&)(const int*) -> auto&>; // { dg-error "template argument" } +} + +void +g () +{ + t<auto(&)(const int*) -> auto&>; // { dg-error "template argument" } +} diff --git a/gcc/testsuite/g++.dg/concepts/auto8a.C b/gcc/testsuite/g++.dg/concepts/auto8a.C new file mode 100644 index 00000000000..fc60dc871c2 --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/auto8a.C @@ -0,0 +1,18 @@ +// PR c++/110065 +// { dg-do compile { target c++17 } } +// { dg-additional-options -fconcepts-ts } + +template <typename> +inline constexpr bool t = false; + +int +f () +{ + return t<auto(&)(const int*) -> auto&>; // { dg-error "template argument" } +} + +void +g () +{ + t<auto(&)(const int*) -> auto&>; // { dg-error "template argument" } +}