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