On Mar 30, 2018, Jason Merrill <ja...@redhat.com> wrote: > True, it looks like sometimes we build a TEMPLATE_ID_EXPR with an > IDENTIFIER_NODE. Looking at tsubst_copy_and_build, I see that we > don't call finish_id_expression when substituting such a > TEMPLATE_ID_EXPR. So maybe lookup_template_function and > lookup_template_variable are the right places for this test.
Nevermind the earlier email about multiple errors. I realized that we save the preparsed template_id right after the tests in cp_parser_template_id, and if only I don't stop the rejected template from being saved, we avoid the duplicate errors, as in the patch below. A slight variant of this passed regstrap on i686- and x86_64-linux-gnu. Ok to install, though it does not catch such cases as: template <typename T> void foo(T t) { typename T::template C<auto> u = t; T::template C<auto> (t); T::template C<auto>::f (t, u); } ? [PR c++/84979] reject auto in explicit tmpl args for tmpl-fn With concepts, we accept auto in explicit template arguments, but we should only accept them for template classes. Passing them to template functions is not allowed. So, reject it. for gcc/cp/ChangeLog PR c++/84979 * parser.c (cp_parser_check_for_auto_in_templ_arguments): New. (cp_parser_template_id): Use it to reject template args referencing auto for non-type templates. for gcc/testsuite/ChangeLog PR c++/84979 * g++.dg/concepts/pr84979.C: New. --- gcc/cp/parser.c | 39 +++++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/concepts/pr84979.C | 9 +++++++ 2 files changed, 48 insertions(+) create mode 100644 gcc/testsuite/g++.dg/concepts/pr84979.C diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index e946d0b72292..c5ba2123ae96 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -15690,6 +15690,42 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack) return parameter; } +/* If concepts are enabled and TEMPL does not identify a template + class, report occurrences of auto types in ARGUMENTS. Return TRUE + if any such errors were reported. */ + +static bool +cp_parser_check_for_auto_in_templ_arguments (cp_parser *parser ATTRIBUTE_UNUSED, + tree templ, + tree arguments) +{ + if (!flag_concepts) + return false; + + if (identifier_p (templ) + || DECL_TYPE_TEMPLATE_P (templ) + || DECL_TEMPLATE_TEMPLATE_PARM_P (templ)) + return false; + + if (!arguments || TREE_CODE (arguments) != TREE_VEC) + return false; + + bool errors = false; + + for (int i = 0; i < TREE_VEC_LENGTH (arguments); i++) + { + tree xauto = type_uses_auto (TREE_VEC_ELT (arguments, i)); + if (xauto) + { + error_at (DECL_SOURCE_LOCATION (TEMPLATE_TYPE_DECL (xauto)), + "invalid use of %<auto%> in template argument"); + errors = true; + } + } + + return errors; +} + /* Parse a template-id. template-id: @@ -15851,6 +15887,9 @@ cp_parser_template_id (cp_parser *parser, template_id = finish_template_type (templ, arguments, entering_scope); } + else if (cp_parser_check_for_auto_in_templ_arguments (parser, templ, + arguments)) + template_id = error_mark_node; /* A template-like identifier may be a partial concept id. */ else if (flag_concepts && (template_id = (cp_parser_maybe_partial_concept_id diff --git a/gcc/testsuite/g++.dg/concepts/pr84979.C b/gcc/testsuite/g++.dg/concepts/pr84979.C new file mode 100644 index 000000000000..c70b3756f2b8 --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/pr84979.C @@ -0,0 +1,9 @@ +// { dg-do compile { target c++11 } } +// { dg-options "-fconcepts" } + +template<typename> void foo() {} + +void bar() +{ + foo<auto>(); // { dg-error "invalid|no match" } +} -- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer