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: C++ PATCH for c++/85977, array reference size deduction failure


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


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