Tested x86_64-pc-linux-gnu, applying to trunk. -- 8< --
We were failing to diagnose this Concepts TS feature that didn't make it into C++20 because the 'auto' was getting converted to a template parameter before we checked for it. So also check in cp_parser_simple_type_specifier. The code in cp_parser_template_type_arg that I initially expected to diagnose this seems unreachable because cp_parser_type_id_1 already checks auto. gcc/cp/ChangeLog: * parser.cc (cp_parser_simple_type_specifier): Check for auto in template argument. (cp_parser_template_type_arg): Remove auto checking. gcc/testsuite/ChangeLog: * g++.dg/concepts/auto7.C: New test. * g++.dg/concepts/auto7a.C: New test. --- gcc/cp/parser.cc | 17 ++++++++--------- gcc/testsuite/g++.dg/concepts/auto7.C | 9 +++++++++ gcc/testsuite/g++.dg/concepts/auto7a.C | 8 ++++++++ 3 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/g++.dg/concepts/auto7.C create mode 100644 gcc/testsuite/g++.dg/concepts/auto7a.C diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index d77fbd20e56..09cba713437 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -19823,15 +19823,19 @@ cp_parser_simple_type_specifier (cp_parser* parser, "only available with " "%<-std=c++14%> or %<-std=gnu++14%>"); } + else if (!flag_concepts_ts && parser->in_template_argument_list_p) + pedwarn (token->location, 0, + "use of %<auto%> in template argument " + "only available with %<-fconcepts-ts%>"); + else if (!flag_concepts) + pedwarn (token->location, 0, + "use of %<auto%> in parameter declaration " + "only available with %<-std=c++20%> or %<-fconcepts%>"); else if (cxx_dialect < cxx14) error_at (token->location, "use of %<auto%> in parameter declaration " "only available with " "%<-std=c++14%> or %<-std=gnu++14%>"); - else if (!flag_concepts) - pedwarn (token->location, 0, - "use of %<auto%> in parameter declaration " - "only available with %<-std=c++20%> or %<-fconcepts%>"); } else type = make_auto (); @@ -24522,11 +24526,6 @@ cp_parser_template_type_arg (cp_parser *parser) = G_("types may not be defined in template arguments"); r = cp_parser_type_id_1 (parser, CP_PARSER_FLAGS_NONE, true, false, NULL); parser->type_definition_forbidden_message = saved_message; - if (cxx_dialect >= cxx14 && !flag_concepts && 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/auto7.C b/gcc/testsuite/g++.dg/concepts/auto7.C new file mode 100644 index 00000000000..3cbf5dd8dfc --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/auto7.C @@ -0,0 +1,9 @@ +// { dg-do compile { target c++14 } } +// { dg-additional-options -fconcepts-ts } + +template <class T> struct A { }; +void f(A<auto> a) { } +int main() +{ + f(A<int>()); +} diff --git a/gcc/testsuite/g++.dg/concepts/auto7a.C b/gcc/testsuite/g++.dg/concepts/auto7a.C new file mode 100644 index 00000000000..88868f45d1c --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/auto7a.C @@ -0,0 +1,8 @@ +// { dg-do compile { target c++14 } } + +template <class T> struct A { }; +void f(A<auto> a) { } // { dg-error "auto. in template argument" } +int main() +{ + f(A<int>()); +} base-commit: 3e12669a0eb968cfcbe9242b382fd8020935edf8 -- 2.31.1