On 9/2/21 8:10 PM, Barrett Adair wrote:
Thanks for the feedback, Jason. Coming back to this today, The problem appears much deeper than I realized. I've attached another WIP version of the patch, including a couple of new test cases based on your feedback (for now, please excuse any misformatted dg-error comments).

The dependent-name16.C case demonstrates an error message regression caused by this patch; I'm trying to fix the regression. When compiling dependent-name16.C and breaking at cp/tree.c:3922, DECL_CONTEXT(t2) is NULL because the "g" declaration is still being parsed near the top of cp_parser_init_declarator, and context is only set later during that function. DECL_CONTEXT(t1), on the other hand, is set because the "f" declaration was already parsed.

I'm beginning to believe that a proper solution to this problem would require decorating the function template type parameter nodes with more function information (e.g. at least scope and name) prior to parsing the trailing return type, if not somehow setting the DECL_CONTEXT earlier in some form -- am I missing something?

Perhaps comparing DECL_SOURCE_LOCATION would be useful?

But actually, I suspect you're approaching this the wrong way: the problem in canon-type-15.C is "internal compiler error: canonical types differ for identical types ‘size_c<sizeof (t)>’ and ‘size_c<sizeof (t)>’".

The intent is that template arguments involving with distinct but equivalent arguments should themselves be distinct but equivalent: different tree nodes, but the same TYPE_CANONICAL.

That isn't happening here: they're different tree nodes and have different TYPE_CANONICAL, so they're considered non-equivalent, but structurally compare as equivalent, so we get the ICE above. We need to fix TYPE_CANONICAL to match.

I think a straightforward approach would be to make any_template_arguments_need_structural_equality_p return true if one of the template arguments involves a function parameter, so that TYPE_CANONICAL gets set to 0 and we always do structural comparison in that context.

Also, in the first place, I'm a little confused why we insert dependent-arg instantiations into the specialization/instantiation hash tables before any top-level instantiation occurs. From a bird's eye view, the benefit/necessity of this design is unclear. Can anyone point me to some background reading here?

So that whenever we write e.g. A<T> we get the same type node.

Jason

Reply via email to