https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109531
--- Comment #11 from Jakub Jelinek ---
Better don't reuse U for two different parameters:
template
using A = int *;
template class U>
struct B { typedef U type; };
struct C { typedef int *type; };
template
struct D {
D foo () { return D (); }
template class V>
V bar ();
};
struct E { typedef int type; };
D > d;
The ICE is on
(gdb) p debug_tree (*entry)
unsigned DI
size
unit-size
align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7fffea157b28>>
index 0 level 1 orig_level 2
chain >
$14 = void
(gdb) p debug_tree (comparable)
unsigned DI
size
unit-size
align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7fffea157b28>>
index 0 level 1 orig_level 2
chain >
$15 = void
Both of these BOUND_TEMPLATE_TEMPLARE_PARMs are created in
#4 0x01462bbc in copy_node (node=) at ../../gcc/tree.cc:1334
#5 0x005d9d68 in copy_type (type=) at ../../gcc/cp/lex.cc:1067
#6 0x00767b5f in tsubst (t=, args=, complain=1,
in_decl=)
at ../../gcc/cp/pt.cc:16262
#7 0x00765155 in tsubst_function_type (t=,
args=, complain=1, in_decl=)
at ../../gcc/cp/pt.cc:15649
#8 0x007687af in tsubst (t=,
args=, complain=1, in_decl=) at ../../gcc/cp/pt.cc:16468
#9 0x0075afd2 in tsubst_function_decl (t=, args=, complain=1, lambda_fntype=)
at ../../gcc/cp/pt.cc:14419
#10 0x0075df67 in tsubst_template_decl (t=, args=, complain=1, lambda_fntype=)
at ../../gcc/cp/pt.cc:14730
#11 0x007613a1 in tsubst_decl (t=,
args=, complain=1) at ../../gcc/cp/pt.cc:14892
#12 0x00765f8e in tsubst (t=,
args=, complain=1, in_decl=) at
../../gcc/cp/pt.cc:15933
and
#4 0x01462bbc in copy_node (node=) at ../../gcc/tree.cc:1334
#5 0x005d9d68 in copy_type (type=) at ../../gcc/cp/lex.cc:1067
#6 0x00767b5f in tsubst (t=, args=, complain=1,
in_decl=)
at ../../gcc/cp/pt.cc:16262
#7 0x00765155 in tsubst_function_type (t=,
args=, complain=1, in_decl=)
at ../../gcc/cp/pt.cc:15649
#8 0x007687af in tsubst (t=,
args=, complain=1, in_decl=) at ../../gcc/cp/pt.cc:16468
#9 0x0075afd2 in tsubst_function_decl (t=, args=, complain=1, lambda_fntype=)
at ../../gcc/cp/pt.cc:14419
#10 0x0075df67 in tsubst_template_decl (t=, args=, complain=1, lambda_fntype=)
at ../../gcc/cp/pt.cc:14730
#11 0x007613a1 in tsubst_decl (t=,
args=, complain=1) at ../../gcc/cp/pt.cc:14892
#12 0x00765f8e in tsubst (t=,
args=, complain=1, in_decl=) at
../../gcc/cp/pt.cc:15933
The first one being bar instantiation with C arg, the latter with B arg.
When hashing those, the difference is in
if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
val = iterative_hash_template_arg (TYPE_TI_ARGS (t), val);
which is a TREE_VEC containing
unit-size
align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7fffea14f5e8 precision:32 min max
pointer_to_this >
unsigned DI
size constant 64>
unit-size constant 8>
align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7fffea157b28>
in one case and
unit-size
align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7fffea14f5e8 precision:32 min max
pointer_to_this >
unsigned DI
size constant 64>
unit-size constant 8>
align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7fffea157b28>
in another.
In the second case it triggers
if (tree ats = alias_template_specialization_p (arg, nt_transparent))
{
// We want an alias specialization that survived strip_typedefs
// to hash differently from its TYPE_CANONICAL, to avoid hash
// collisions that compare as different in template_args_equal.
// These could be dependent specializations that strip_typedefs
// left alone, or untouched specializations because
// coerce_template_parms returns the unconverted template
// arguments if it sees incomplete argument packs.
tree ti = TYPE_ALIAS_TEMPLATE_INFO (ats);
return hash_tmpl_and_args (TI_TEMPLATE (ti), TI_ARGS (ti));
}
in iterative_hash_template_arg, while in the first case it doesn't and it gets
default:
if (tree canonical = TYPE_CANONICAL (arg))
val = iterative_hash_object (TYPE_HASH (canonical), val);
and so they hash differently. But apparently structural_comptypes thinks they
are equal.