https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121932
--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #5)
> (In reply to Andrew Pinski from comment #4)
> > Reduced further to:
> > ```
> > struct s1{
> > template <long N> void f(int (&)[N]);
> > };
> > struct s2{
> > void f(const s1);
> > };
> > void s2::f(const s1) {}
> > ```
> >
> > If we make s2::f not a member function of s2 but rather a global function
> > GCC does NOT ICE.
>
> Also removing the const causes the ICE to go away.
There is this code in free_lang_data_in_type:
/* Remove the const and volatile qualifiers from arguments. The
C++ front end removes them, but the C front end does not,
leading to false ODR violation errors when merging two
instances of the same function signature compiled by
different front ends. */
for (tree p = TYPE_ARG_TYPES (type); p; p = TREE_CHAIN (p))
{
tree arg_type = TREE_VALUE (p);
if (TYPE_READONLY (arg_type) || TYPE_VOLATILE (arg_type))
{
int quals = TYPE_QUALS (arg_type)
& ~TYPE_QUAL_CONST
& ~TYPE_QUAL_VOLATILE;
TREE_VALUE (p) = build_qualified_type (arg_type, quals);
if (!fld->pset.add (TREE_VALUE (p)))
free_lang_data_in_type (TREE_VALUE (p), fld);
}
TREE_VALUE (p) = fld_simplified_type (TREE_VALUE (p), fld);
/* C++ FE uses TREE_PURPOSE to store initial values. */
TREE_PURPOSE (p) = NULL;
}
I don't know if this is being hit though.