[Bug c++/109531] [13 Regression] Checking ICE with hash table checking failed: equal operator returns true for a pair of values with a different hash value since r13-3292-gc2565a31c1622a

2023-04-17 Thread ppalka at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109531

--- Comment #12 from Patrick Palka  ---
I suppose we're just neglecting to canonicalize a bound ttp's substituted args
before determining its canonical type.  Adding a call to coerce_template_parms
or canonicalize_type_argument seems to fix it:

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index fcc8e0d1d57..5ff91414f69 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -16285,9 +16285,18 @@ tsubst (tree t, tree args, tsubst_flags_t complain,
tree in_decl)
  return error_mark_node;
tree argvec = tsubst (TI_ARGS (tinfo), args,
  complain, in_decl);
+   // this fixes it
+   tree tparms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
+   argvec = coerce_template_parms (tparms, argvec,
+   tmpl, complain);
if (argvec == error_mark_node)
  return error_mark_node;

+   // or this
+   for (tree& arg : tree_vec_range (argvec))
+ if (TYPE_P (arg))
+   arg = canonicalize_type_argument (arg, complain);
+
TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (r)
  = build_template_info (tmpl, argvec);
  }

[Bug c++/109531] [13 Regression] Checking ICE with hash table checking failed: equal operator returns true for a pair of values with a different hash value since r13-3292-gc2565a31c1622a

2023-04-17 Thread jakub at gcc dot gnu.org via Gcc-bugs
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.

[Bug c++/109531] [13 Regression] Checking ICE with hash table checking failed: equal operator returns true for a pair of values with a different hash value since r13-3292-gc2565a31c1622a

2023-04-17 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109531

Jakub Jelinek  changed:

   What|Removed |Added

   Target Milestone|--- |13.0

[Bug c++/109531] [13 Regression] Checking ICE with hash table checking failed: equal operator returns true for a pair of values with a different hash value since r13-3292-gc2565a31c1622a

2023-04-17 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109531

--- Comment #10 from Jakub Jelinek  ---
Slightly cleaned up:

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 U>
  U  bar ();
};
struct E { typedef int type; };
D > d;

As no floating point types are involved, I think this had to be latent before.

[Bug c++/109531] [13 Regression] Checking ICE with hash table checking failed: equal operator returns true for a pair of values with a different hash value since r13-3292-gc2565a31c1622a

2023-04-17 Thread marxin at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109531

Martin Liška  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org
Summary|Checking ICE with  hash |[13 Regression] Checking
   |table checking failed:  |ICE with  hash table
   |equal operator returns true |checking failed: equal
   |for a pair of values with a |operator returns true for a
   |different hash value|pair of values with a
   ||different hash value since
   ||r13-3292-gc2565a31c1622a

--- Comment #9 from Martin Liška  ---
Started with r13-3292-gc2565a31c1622a.