This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] [PR c++/84979] improve auto handling in explicit tmpl args for concepts


On Tue, Apr 3, 2018 at 10:38 PM, Alexandre Oliva <aoliva@redhat.com> wrote:
> On Apr  3, 2018, Jason Merrill <jason@redhat.com> wrote:
>
>> On Tue, Apr 3, 2018 at 3:54 AM, Alexandre Oliva <aoliva@redhat.com> wrote:
>>> On Apr  2, 2018, Jason Merrill <jason@redhat.com> wrote:
>>>
>>>> On Sat, Mar 31, 2018 at 4:23 AM, Alexandre Oliva <aoliva@redhat.com> wrote:
>>>>> On Mar 30, 2018, Jason Merrill <jason@redhat.com> wrote:
>>>>> 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);
>>>>> }
>>>
>>>> We should be able to distinguish those cases based on tag_type.
>
>>> [...]
>>> And then, while we're parsing "template C<auto>", we haven't yet reached
>>> the '::' after the closing angle bracket that would tell us to regard
>>> the id necessarily as a typename, so I don't see how we'd get a
>>> scope_type in tag_type for the third case.
>
>> Ah, good point.  Then perhaps put the new function in pt.c and also
>> call it from tsubst_copy_and_build?
>
> I couldn't figure out how to trigger checks in tsubst_copy_and_build;
> the testcases I threw at it all went through tsubst_qualified_id.  I
> think we can only get an identifier_p in a TEMPLATE_ID_EXPR when it's a
> qualified id naming a member of another template; unqualified names that
> could possibly take explicit template arguments would have to have
> visible declarations, and then we'd get (an overload of) the
> declarations in the TEMPLATE_ID_EXPR.  I see evidence in pt.c that some
> cases of Koenig lookup may involve identifier_p template substitution,
> and I see evidence in the standard that the unqualified template-id
> could have explicit template args, but...  we won't regard <whatever> as
> a template arg list if it's not preceded by an id that names a template,
> be it a template-dependent qualified id preceded by the 'template'
> keyword, be a template found by name lookup.  If we find an unrelated
> template function (as in the snippet below), we'll stick to it.  So it
> seems to me that the patch below is all we need.  Am I missing anything?
>
> struct foo { template <typename T> friend void bar(T& t); };
> template <int> void bar();
> template <typename T> void f(T& x) { bar<auto> (x); }
> void g(foo& x) { f (x); }
>
>
> Regstrapping on i686- and x86_64-linux-gnu.  Ok to install if it passes?
>
>
> [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 or variables is not allowed.  So, reject it, at
> parse time if possible, at specialization time otherwise.
>
>
> for  gcc/cp/ChangeLog
>
>         PR c++/84979
>         * pt.c (check_auto_in_tmpl_args): New.
>         (tsubst_qualified_id): Use it to reject template args
>         referencing auto for non-type templates.
>         * parser.c (cp_parser_template_id): Likewise.
>         * cp-tree.h (check_auto_in_tmpl_args): Declare.
>         * typeck2.c (build_functional_cast): Report correct location
>         for invalid use of auto.
>
> for  gcc/testsuite/ChangeLog
>
>         PR c++/84979
>         * g++.dg/concepts/pr84979.C: New.
>         * g++.dg/concepts/pr84979-2.C: New.
>         * g++.dg/concepts/pr84979-3.C: New.
> ---
>  gcc/cp/cp-tree.h                          |    1 +
>  gcc/cp/parser.c                           |   10 +++++-
>  gcc/cp/pt.c                               |   52 +++++++++++++++++++++++++++++
>  gcc/cp/typeck2.c                          |    3 +-
>  gcc/testsuite/g++.dg/concepts/pr84979-2.C |   41 +++++++++++++++++++++++
>  gcc/testsuite/g++.dg/concepts/pr84979-3.C |   45 +++++++++++++++++++++++++
>  gcc/testsuite/g++.dg/concepts/pr84979.C   |    9 +++++
>  7 files changed, 159 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/concepts/pr84979-2.C
>  create mode 100644 gcc/testsuite/g++.dg/concepts/pr84979-3.C
>  create mode 100644 gcc/testsuite/g++.dg/concepts/pr84979.C
>
> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
> index db79338035da..4777aa34cdbe 100644
> --- a/gcc/cp/cp-tree.h
> +++ b/gcc/cp/cp-tree.h
> @@ -6496,6 +6496,7 @@ extern void maybe_show_extern_c_location (void);
>
>  /* in pt.c */
>  extern bool check_template_shadow              (tree);
> +extern bool check_auto_in_tmpl_args             (tree, tree);
>  extern tree get_innermost_template_args                (tree, int);
>  extern void maybe_begin_member_template_processing (tree);
>  extern void maybe_end_member_template_processing (void);
> diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
> index e946d0b72292..40a1e5549f02 100644
> --- a/gcc/cp/parser.c
> +++ b/gcc/cp/parser.c
> @@ -15831,8 +15831,16 @@ cp_parser_template_id (cp_parser *parser,
>    location_t combined_loc
>      = make_location (token->location, token->location, finish_loc);
>
> +  /* Check for concepts autos where they don't belong.  We could
> +     identify types in some cases of idnetifier TEMPL, looking ahead
> +     for a CPP_SCOPE, but that would buy us nothing: we accept auto in
> +     types.  We reject them in functions, but if what we have is an
> +     identifier, even with none_type we can't conclude it's NOT a
> +     type, we have to wait for template substitution.  */
> +  if (flag_concepts && check_auto_in_tmpl_args (templ, arguments))
> +    template_id = error_mark_node;
>    /* Build a representation of the specialization.  */
> -  if (identifier_p (templ))
> +  else if (identifier_p (templ))
>      template_id = build_min_nt_loc (combined_loc,
>                                     TEMPLATE_ID_EXPR,
>                                     templ, arguments);
> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
> index 284eaf3cab66..a5c489fc0768 100644
> --- a/gcc/cp/pt.c
> +++ b/gcc/cp/pt.c
> @@ -14890,6 +14890,15 @@ tsubst_qualified_id (tree qualified_id, tree args,
>                                                     complain);
>        else
>         expr = lookup_template_function (expr, template_args);
> +
> +      /* We may be repeating a check already done during parsing, but
> +        if it was well-formed and passed then, it will pass again
> +        now, and if it didn't, we wouldn't have got here.  The case
> +        we want to catch is when we couldn't tell then, and can now,
> +        namely when templ prior to substitution was an
> +        identifier.  */
> +      if (flag_concepts && check_auto_in_tmpl_args (expr, template_args))
> +       return error_mark_node;

I think we want this added code to go at the beginning of the block,
before we've wrapped the template in a TEMPLATE_ID_EXPR.  OK with that
change.

Jason


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]