On 01/22/2016 05:30 PM, Patrick Palka wrote:
On Fri, 22 Jan 2016, Jason Merrill wrote:
On 01/22/2016 11:17 AM, Patrick Palka wrote:
On Thu, 21 Jan 2016, Patrick Palka wrote:
On Thu, 21 Jan 2016, Jason Merrill wrote:

On 01/19/2016 10:30 PM, Patrick Palka wrote:
     * g++.dg/template/unify17.C: XFAIL.

Hmm, I'm not comfortable with deliberately regressing this testcase.

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

Can we work it so that T[5] also is un-decayed in the DECL_ARGUMENTS
of bar, but decayed in the TYPE_ARG_TYPES?

I think so, I'll try it.

Well, I tried it and the result is really ugly and it only "somewhat"
works.  (Maybe I'm just missing something obvious though.)  The ugliness
comes from the fact that decaying an array parameter type of a function
type embedded deep within some tree structure requires rebuilding all
the tree structures in between to avoid issues due to tree sharing.

Yes, that does complicate things.

This approach only "somewhat" works because it currently looks through
function, pointer, reference and array types.

Right, you would need to handle template arguments as well.

And I just noticed that
this approach does not work at all for USING_DECLs because no PARM_DECL
is ever retained anyway in that case.

I don't understand what you mean about USING_DECLs.

I just meant that we fail and would continue to fail to diagnose an
"array of void" error in the following test case:

    template <typename T>
    using X = void (T[5]);

    void foo (X<void>);

True.  I think here we want to get the error when instantiating X<void>.

I think a better, complete fix for this issue would be to, one way or
another, be able to get at the PARM_DECLs that correspond to a given
FUNCTION_TYPE.  Say, if, the TREE_CHAIN of a FUNCTION_TYPE optionally
pointed to its PARM_DECLs, or something.  What do you think?

Hmm.  So void(int[5]) and void(int*) would be distinct types, but they
would share TYPE_CANONICAL, as though one is a typedef of the other?
Interesting, but I'm not sure how that would interact with template
argument canonicalization.  Well, that can probably be made to work by
treating dependent template arguments as distinct more frequently.

Another thought: What if we keep a list of arrays we need to
substitute into for a particular function template?

That approach definitely seems easier to reason about.  And it could
properly handle "using" templates as well as variable templates -- any
TEMPLATE_DECL, I think.

Agreed.

Jason

Reply via email to