On Mon, Jan 18, 2016 at 10:34 AM, Jason Merrill <ja...@redhat.com> wrote:
> On 12/25/2015 12:37 PM, Patrick Palka wrote:
>>
>> That alone would not be sufficient because more_specialized_fn()
>> doesn't call maybe_adjust_types_for_deduction() beforehand, yet we
>> have to do the decaying there too (and on both types, not just one of
>> them).
>>
>> And maybe_adjust_types_for_deduction() seems to operate on the
>> presumption that one type is the parameter type and one is the
>> argument type. But in more_specialized_fn() and in get_bindings() we
>> are really working with two parameter types and have to decay them
>> both. So sometimes we have to decay one of the types that are
>> eventually going to get passed to unify(), and other times we want to
>> decay both types that are going to get passed to unify().
>> maybe_adjust_types_for_deduction() seems to only expect the former
>> case.
>>
>> Finally, maybe_adjust_types_for_deduction() is not called when
>> unifying a nested function declarator (because it is guarded by the
>> subr flag in unify_one_argument), so doing it there we would also
>> regress in the following test case:
>
>
> Ah, that makes sense.
>
> How about keeping the un-decayed type in the PARM_DECLs, so that we get the
> substitution failure in instantiate_template, but having the decayed type in
> the TYPE_ARG_TYPES, probably by doing the decay in grokparms, so it's
> already decayed when we're doing unification?

I just tried this, and it works well! With this approach, all but one
of the test cases pass.  The failing test case is unify17.C:

-- 8< --

void foo (int *);

template <typename T>
void bar (void (T[5])); // { dg-error "array of 'void'" }

void
baz (void)
{
  bar<void> (0); // { dg-error "no matching function" }
}

-- 8< --

Here, we don't get a substitution failure because we don't have a
corresponding FUNCTION_DECL for the nested function specifier, only a
FUNCTION_TYPE. So there is no PARM_DECL to recurse into during
substitution, that retains the un-decayed argument type "T[5]" of the
nested function specifier.

I'm not yet sure how to work around this...

Reply via email to