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