https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87847
--- Comment #2 from Marek Polacek <mpolacek at gcc dot gnu.org> --- In the ttp23.C testcase we're comparing B<Q> and B<Q>. In one case the template argument is <tree_vec 0x7fffeab33920 length:1 elt:0 <template_template_parm 0x7fffeab3ad20 VOID align:8 warn_if_not_align:0 symtab:0 alias-set -1 structural-equality index 0 level 1 orig_level 2 chain <template_decl 0x7fffea9f8b80 Q>>> and the other is <tree_vec 0x7fffeab33560 length:1 elt:0 <template_template_parm 0x7fffeab3a348 VOID align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7fffeab25c78 index 0 level 1 orig_level 1 chain <template_decl 0x7fffea9f8680 Q>>> same_type_p says they're same, so comp_template_args returns true. One of the template_template_parms has TYPE_CANONICAL, so we hash it as: 1905 if (TYPE_CANONICAL (arg)) 1906 return iterative_hash_object (TYPE_HASH (TYPE_CANONICAL (arg)), 1907 val); but the other type doesn't have a canonical type: 1910 /* Otherwise just compare the types during lookup. */ 1911 return val; so the hashes end up being different.