C++ PATCH for c++/85977, array reference size deduction failure

Jason Merrill jason@redhat.com
Fri Jun 1 16:39:00 GMT 2018


On Fri, Jun 1, 2018 at 11:52 AM, Marek Polacek <polacek@redhat.com> wrote:
> 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).

Yes, we still need to do deduction on the array bound, so we can't
return immediately.  We just want to avoid the

      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt)

loop.

Jason



More information about the Gcc-patches mailing list