c++: ttp TEMPLATE_DECL equivalence [PR112737]
commit3ba5be16a2be3eaedf2870ca1e25cfe826945948
authorPatrick Palka <ppalka@redhat.com>
Thu, 1 Feb 2024 18:17:48 +0000 (1 13:17 -0500)
committerPatrick Palka <ppalka@redhat.com>
Thu, 1 Feb 2024 18:17:48 +0000 (1 13:17 -0500)
tree80ffe11525affcc16c60e4849b6cf8d88e467e44
parenta886a90625a4ba5e1cc3270e69735cc4fe51f19c
c++: ttp TEMPLATE_DECL equivalence [PR112737]

Here during declaration matching we undesirably consider the two TT{42}
CTAD expressions to be non-equivalent ultimately because for CTAD
placeholder equivalence we compare the TEMPLATE_DECLs via pointer identity,
and here the corresponding TEMPLATE_DECLs for TT are different since
they're from different scopes.  On the other hand, the corresponding
TEMPLATE_TEMPLATE_PARMs are deemed equivalent according to cp_tree_equal
(since they have the same position and template parameters).  This turns
out to be the root cause of some of the xtreme-header modules regressions.

So this patch relaxes ttp CTAD placeholder equivalence accordingly, by
comparing the TEMPLATE_TEMPLATE_PARM instead of the TEMPLATE_DECL.  It
turns out this issue also affects function template-id equivalence as
with g<TT> in the second testcase, so it makes sense to relax TEMPLATE_DECL
equivalence more generally in cp_tree_equal.  In passing this patch
improves ctp_hasher::hash for CTAD placeholders, so that they don't
all get the same hash.

PR c++/112737

gcc/cp/ChangeLog:

* pt.cc (iterative_hash_template_arg) <case TEMPLATE_DECL>:
Adjust hashing to match cp_tree_equal.
(ctp_hasher::hash): Also hash CLASS_PLACEHOLDER_TEMPLATE.
* tree.cc (cp_tree_equal) <case TEMPLATE_DECL>: Return true
for ttp TEMPLATE_DECLs if their TEMPLATE_TEMPLATE_PARMs are
equivalent.
* typeck.cc (structural_comptypes) <case TEMPLATE_TYPE_PARM>:
Use cp_tree_equal to compare CLASS_PLACEHOLDER_TEMPLATE.

gcc/testsuite/ChangeLog:

* g++.dg/template/ttp42.C: New test.
* g++.dg/template/ttp43.C: New test.

Reviewed-by: Jason Merrill <jason@redhat.com>
gcc/cp/pt.cc
gcc/cp/tree.cc
gcc/cp/typeck.cc
gcc/testsuite/g++.dg/template/ttp42.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/ttp43.C [new file with mode: 0644]