On Mon, Jun 17, 2024 at 03:33:05PM +0200, Martin Uecker wrote: > > I've done that and that was because build_qualified_type uses that > > predicate, where qualified types created by build_qualified_type have > > as TYPE_CANONICAL the qualified type of the main variant of the canonical > > type, while in all other cases TYPE_CANONICAL is just the main variant of > > the type. > > Guess we could also just do > > if (TYPE_QUALS (x) == TYPE_QUALS (t)) > > TYPE_CANONICAL (x) = TYPE_CANONICAL (t); > > else if (TYPE_CANONICAL (t) != t > > || TYPE_QUALS (x) != TYPE_QUALS (TYPE_CANONICAL (t))) > > TYPE_CANONICAL (x) > > = build_qualified_type (TYPE_CANONICAL (t), TYPE_QUALS (x)); > > else > > TYPE_CANONICAL (x) = x; > > > > Ok, that works. I think the final "else" is then then impossible to reach > and can be eliminated as well, because if TYPE_CANONICAL (t) == t then > TYPE_QUALS (x) == TYPE_QUALS (TYPE_CANONICAL (t)) is identical to > TYPE_QUALS (x) == TYPE_QUALS (t) which is the first case.
If c_update_type_canonical is only ever called for the main variants of the type and they always have !TYPE_QUALS (t), then yes. But if we rely on that, perhaps we should gcc_checking_assert that. So gcc_checking_assert (t == TYPE_MAIN_VARIANT (t) && !TYPE_QUALS (t)); or something similar at the start of the function. Then we could also change the for (tree x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x)) to for (tree x = t; x; x = TYPE_NEXT_VARIANT (x)) and if (TYPE_QUALS (x) == TYPE_QUALS (t)) ... to if (!TYPE_QUALS (x)) TYPE_CANONICAL (x) = TYPE_CANONICAL (t); else build_qualified_type (TYPE_CANONICAL (t), TYPE_QUALS (x)); Jakub