https://gcc.gnu.org/g:f043803dea58609d2d8a75b1d861b939aeb9f86e
commit r16-8986-gf043803dea58609d2d8a75b1d861b939aeb9f86e Author: Eric Botcazou <[email protected]> Date: Wed Jan 21 19:12:02 2026 +0100 ada: Fix crash on equality of unchecked union components of formal parameters The bottom line is that we need to suspend the B.3.3(23/2) rule during the expansion of the equality function of an unchecked union itself containing a component of an unchecked union type subject to a per-object constraint, but this was done too broadly instead of specifically for this case. gcc/ada/ChangeLog: * sem_util.adb (Prefix_Is_Formal_Parameter): Rename into... (Prefix_Is_Formal_Parameter_Of_EQ): ...this. Return True only if the formal parameter is that of an equality function built for an unchecked union type. (Has_Inferable_Discriminants): Adjust to above renaming. Diff: --- gcc/ada/sem_util.adb | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index 67cc363869cf..9ef5de29f644 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -12493,15 +12493,16 @@ package body Sem_Util is function Has_Inferable_Discriminants (N : Node_Id) return Boolean is - function Prefix_Is_Formal_Parameter (N : Node_Id) return Boolean; - -- Determines whether the left-most prefix of a selected component is a - -- formal parameter in a subprogram. Assumes N is a selected component. + function Prefix_Is_Formal_Parameter_Of_EQ (N : Node_Id) return Boolean; + -- Determines whether the left-most prefix of selected component N + -- is a formal parameter of the predefined equality function of an + -- Unchecked_Union type. - -------------------------------- - -- Prefix_Is_Formal_Parameter -- - -------------------------------- + -------------------------------------- + -- Prefix_Is_Formal_Parameter_Of_EQ -- + -------------------------------------- - function Prefix_Is_Formal_Parameter (N : Node_Id) return Boolean is + function Prefix_Is_Formal_Parameter_Of_EQ (N : Node_Id) return Boolean is Sel_Comp : Node_Id; begin @@ -12514,8 +12515,10 @@ package body Sem_Util is Sel_Comp := Parent (Sel_Comp); end loop; - return Is_Formal (Entity (Prefix (Sel_Comp))); - end Prefix_Is_Formal_Parameter; + return Is_Formal (Entity (Prefix (Sel_Comp))) + and then + Is_Unchecked_Union_Equality (Scope (Entity (Prefix (Sel_Comp)))); + end Prefix_Is_Formal_Parameter_Of_EQ; -- Start of processing for Has_Inferable_Discriminants @@ -12533,14 +12536,14 @@ package body Sem_Util is return False; end if; - -- A small hack. If we have a per-object constrained selected - -- component of a formal parameter, return True since we do not - -- know the actual parameter association yet. + -- We need to return True for the component of a formal parameter + -- of the predefined equality function of an Unchecked_Union type + -- when expanding it (see Expand_Unchecked_Union_Equality). return not Has_Per_Object_Constraint (Entity (Selector_Name (N))) or else not Is_Unchecked_Union (Etype (Prefix (N))) or else Has_Inferable_Discriminants (Prefix (N)) - or else Prefix_Is_Formal_Parameter (N); + or else Prefix_Is_Formal_Parameter_Of_EQ (N); -- A qualified expression has inferable discriminants if its subtype -- mark is a constrained Unchecked_Union subtype.
