https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109531

--- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Better don't reuse U for two different parameters:
template <class>
using A = int *;
template <class T, template <class> class U>
struct B { typedef U <typename T::type> type; };
struct C { typedef int *type; };
template <class T>
struct D {
  D <C> foo () { return D <C> (); }
  template <template <class> class V>
  V <typename T::type> bar ();
};
struct E { typedef int type; };
D <B <E, A>> d;

The ICE is on
(gdb) p debug_tree (*entry)
 <bound_template_template_parm 0x7fffea2f01f8 V type_0 type_6 VOID
    align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7fffea2f01f8
    args <tree_vec 0x7fffea2f10c0 length:1
        elt:0 <pointer_type 0x7fffea2ed1f8 type type <integer_type
0x7fffea14f5e8 int>
            unsigned DI
            size <integer_cst 0x7fffea12cfc0 constant 64>
            unit-size <integer_cst 0x7fffea12cfd8 constant 8>
            align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7fffea157b28>>
   index 0 level 1 orig_level 2
    chain <type_decl 0x7fffea2ebed8 V>>
$14 = void
(gdb) p debug_tree (comparable)
 <bound_template_template_parm 0x7fffea2f8540 V type_0 type_6 VOID
    align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7fffea2eda80
    args <tree_vec 0x7fffea2f16a0 length:1
        elt:0 <pointer_type 0x7fffea2f87e0 type type <integer_type
0x7fffea14f5e8 int>
            unsigned DI
            size <integer_cst 0x7fffea12cfc0 constant 64>
            unit-size <integer_cst 0x7fffea12cfd8 constant 8>
            align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7fffea157b28>>
   index 0 level 1 orig_level 2
    chain <type_decl 0x7fffea2f2850 V>>
$15 = void
Both of these BOUND_TEMPLATE_TEMPLARE_PARMs are created in
#4  0x0000000001462bbc in copy_node (node=<bound_template_template_parm
0x7fffea2eda80 V>) at ../../gcc/tree.cc:1334
#5  0x00000000005d9d68 in copy_type (type=<bound_template_template_parm
0x7fffea2eda80 V>) at ../../gcc/cp/lex.cc:1067
#6  0x0000000000767b5f in tsubst (t=<bound_template_template_parm
0x7fffea2eda80 V>, args=<tree_vec 0x7fffea2cec60>, complain=1,
in_decl=<function_decl 0x7fffea2da700 bar>)
    at ../../gcc/cp/pt.cc:16262
#7  0x0000000000765155 in tsubst_function_type (t=<method_type 0x7fffea2edbd0>,
args=<tree_vec 0x7fffea2cec60>, complain=1, in_decl=<function_decl
0x7fffea2da700 bar>)
    at ../../gcc/cp/pt.cc:15649
#8  0x00000000007687af in tsubst (t=<method_type 0x7fffea2edbd0>,
args=<tree_vec 0x7fffea2cec60>, complain=1, in_decl=<function_decl
0x7fffea2da700 bar>) at ../../gcc/cp/pt.cc:16468
#9  0x000000000075afd2 in tsubst_function_decl (t=<function_decl 0x7fffea2da700
bar>, args=<tree_vec 0x7fffea2cec60>, complain=1, lambda_fntype=<tree 0x0>)
    at ../../gcc/cp/pt.cc:14419
#10 0x000000000075df67 in tsubst_template_decl (t=<template_decl 0x7ffff7ffa700
bar>, args=<tree_vec 0x7fffea2cec60>, complain=1, lambda_fntype=<tree 0x0>)
    at ../../gcc/cp/pt.cc:14730
#11 0x00000000007613a1 in tsubst_decl (t=<template_decl 0x7ffff7ffa700 bar>,
args=<tree_vec 0x7fffea2cec60>, complain=1) at ../../gcc/cp/pt.cc:14892
#12 0x0000000000765f8e in tsubst (t=<template_decl 0x7ffff7ffa700 bar>,
args=<tree_vec 0x7fffea2cec60>, complain=1, in_decl=<tree 0x0>) at
../../gcc/cp/pt.cc:15933
and
#4  0x0000000001462bbc in copy_node (node=<bound_template_template_parm
0x7fffea2eda80 V>) at ../../gcc/tree.cc:1334
#5  0x00000000005d9d68 in copy_type (type=<bound_template_template_parm
0x7fffea2eda80 V>) at ../../gcc/cp/lex.cc:1067
#6  0x0000000000767b5f in tsubst (t=<bound_template_template_parm
0x7fffea2eda80 V>, args=<tree_vec 0x7fffea2f1400>, complain=1,
in_decl=<function_decl 0x7fffea2da700 bar>)
    at ../../gcc/cp/pt.cc:16262
#7  0x0000000000765155 in tsubst_function_type (t=<method_type 0x7fffea2edbd0>,
args=<tree_vec 0x7fffea2f1400>, complain=1, in_decl=<function_decl
0x7fffea2da700 bar>)
    at ../../gcc/cp/pt.cc:15649
#8  0x00000000007687af in tsubst (t=<method_type 0x7fffea2edbd0>,
args=<tree_vec 0x7fffea2f1400>, complain=1, in_decl=<function_decl
0x7fffea2da700 bar>) at ../../gcc/cp/pt.cc:16468
#9  0x000000000075afd2 in tsubst_function_decl (t=<function_decl 0x7fffea2da700
bar>, args=<tree_vec 0x7fffea2f1400>, complain=1, lambda_fntype=<tree 0x0>)
    at ../../gcc/cp/pt.cc:14419
#10 0x000000000075df67 in tsubst_template_decl (t=<template_decl 0x7ffff7ffa700
bar>, args=<tree_vec 0x7fffea2f1400>, complain=1, lambda_fntype=<tree 0x0>)
    at ../../gcc/cp/pt.cc:14730
#11 0x00000000007613a1 in tsubst_decl (t=<template_decl 0x7ffff7ffa700 bar>,
args=<tree_vec 0x7fffea2f1400>, complain=1) at ../../gcc/cp/pt.cc:14892
#12 0x0000000000765f8e in tsubst (t=<template_decl 0x7ffff7ffa700 bar>,
args=<tree_vec 0x7fffea2f1400>, complain=1, in_decl=<tree 0x0>) 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
 <pointer_type 0x7fffea2ed1f8 type
    type <integer_type 0x7fffea14f5e8 int public type_6 SI
        size <integer_cst 0x7fffea151210 constant 32>
        unit-size <integer_cst 0x7fffea151228 constant 4>
        align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7fffea14f5e8 precision:32 min <integer_cst 0x7fffea1511c8 -2147483648> max
<integer_cst 0x7fffea1511e0 2147483647>
        pointer_to_this <pointer_type 0x7fffea157b28>>
    unsigned DI
    size <integer_cst 0x7fffea12cfc0 type <integer_type 0x7fffea14f0a8
bitsizetype> constant 64>
    unit-size <integer_cst 0x7fffea12cfd8 type <integer_type 0x7fffea14f000
sizetype> constant 8>
    align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7fffea157b28>
in one case and
 <pointer_type 0x7fffea2f87e0 type
    type <integer_type 0x7fffea14f5e8 int public type_6 SI
        size <integer_cst 0x7fffea151210 constant 32>
        unit-size <integer_cst 0x7fffea151228 constant 4>
        align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7fffea14f5e8 precision:32 min <integer_cst 0x7fffea1511c8 -2147483648> max
<integer_cst 0x7fffea1511e0 2147483647>
        pointer_to_this <pointer_type 0x7fffea157b28>>
    unsigned DI
    size <integer_cst 0x7fffea12cfc0 type <integer_type 0x7fffea14f0a8
bitsizetype> constant 64>
    unit-size <integer_cst 0x7fffea12cfd8 type <integer_type 0x7fffea14f000
sizetype> 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.

Reply via email to