This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: C++ PATCH for c++/85977, array reference size deduction failure
- From: Marek Polacek <polacek at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 1 Jun 2018 11:52:52 -0400
- Subject: Re: C++ PATCH for c++/85977, array reference size deduction failure
- References: <20180530212344.GJ3559@redhat.com> <CADzB+2=EUWAZSNUPMTWJDX76AGxsYDJeRWgf9H7J4qAibbXXLw@mail.gmail.com>
On Thu, May 31, 2018 at 10:11:27AM -0400, Jason Merrill wrote:
> On Wed, May 30, 2018 at 5:23 PM, Marek Polacek <polacek@redhat.com> wrote:
> > We are failing to deduce the template parameter N here
> >
> > template <int N>
> > void foo(const long int (&)[N]) {}
> >
> > void bar() {
> > foo ({1,2,3});
> > }
> >
> > because of the type mismatch; parm is long int (element type of the array),
> > while arg is int (element type of {1, 2, 3}), and unify doesn't like that:
> >
> > 21789 /* We have already checked cv-qualification at the top of the
> > 21790 function. */
> > 21791 if (!same_type_ignoring_top_level_qualifiers_p (arg, parm))
> > 21792 return unify_type_mismatch (explain_p, parm, arg);
> >
> > But since the parameter type is array, we should see if there exists an
> > implicit conversion sequence for each element of the array from the
> > corresponding element of the initializer list, and that's what I tried,
> > and it seems to work.
> >
> > Bootstrapped/regtested on x86_64-linux, ok for trunk?
> >
> > 2018-05-30 Marek Polacek <polacek@redhat.com>
> >
> > PR c++/85977
> > * pt.c (unify): Handle the [over.ics.list]/6 case.
> >
> > + /* [over.ics.list]/6 says we should try an implicit conversion
> > + from each list element to the corresponding array element
> > + type. */
>
> [over.ics.list] doesn't apply during template argument deduction, but
> rather [temp.deduct.call].
Ah, I see.
> > + if (TREE_CODE (parm) == ARRAY_TYPE)
> > + {
> > + tree x = perform_implicit_conversion (elttype, elt, complain);
>
> Rather than check this immediately here, we want to do more or less
> what unify_one_argument does:
>
> if (strict != DEDUCE_EXACT
> && TYPE_P (parm) && !uses_deducible_template_parms (parm))
> /* For function parameters with no deducible template parameters,
> just return. We'll check non-dependent conversions later. */
> return unify_success (explain_p);
>
> so if elttype has no deducible template parms, don't do deduction from
> the list elements at all.
If I return unify_success if !uses_deducible_template_parms (elttype) from
unify, it breaks even the test that worked before (with int instead of long
int), because in type_unification_real we end up calling
20338 return unify_parameter_deduction_failure (explain_p, tparm);
because tparms has N, but targs is empty (i.e. we weren't able to deduce
the template parameter N to 3 in the unify_one_argument call before). And
so...
> And then we want to check convertibility of the elements in
> type_unification_real, when we check convertibility of other function
> parameters that don't involve template parameters:
>
> /* DR 1391: All parameters have args, now check non-dependent
> parms for
> convertibility. */
...we'll never get here.
What am I missing? I suppose what you want to do is to somehow defer the
deducing for later, but I admit I'm lost here.
Marek