https://gcc.gnu.org/g:369b7ed801ed73bf10bba3fc8a858d7102074475

commit r16-3715-g369b7ed801ed73bf10bba3fc8a858d7102074475
Author: Gary Dismukes <dismu...@adacore.com>
Date:   Tue Aug 12 00:26:07 2025 +0000

    ada: Warning for composite equality that calls an abstract equality function
    
    When equality is tested for a composite type that has any record
    components whose type has an abstract equality function that will
    be called as part of the enclosing type's equality, Program_Error
    will be raised.  We now issue a warning on the equality test,
    mentioning the component type whose abstract equality function
    will trigger the exception.  Note that this is currently only
    done for top-level components of the composite type.  Another
    limitation is that the warning is not issued when the outer
    composite type is tagged.
    
    gcc/ada/ChangeLog:
    
            * exp_ch4.adb (Expand_N_Op_Eq): Check for warning about call to
            the abstract equality function of a component type, for both array
            and record enclosing types.
            (Warn_On_Abstract_Equality_For_Component): New procedure to issue
            a warning when an abstract equality function of a component type
            will be called and result in Program_Error.

Diff:
---
 gcc/ada/exp_ch4.adb | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index afdc243d302e..9c987a6fc436 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -8185,6 +8185,11 @@ package body Exp_Ch4 is
       --  Determines whether a type has a subcomponent of an unconstrained
       --  Unchecked_Union subtype. Typ is a record type.
 
+      procedure Warn_On_Abstract_Equality_For_Component
+        (Comp_Type : Entity_Id);
+      --  If Comp_Type has a user-defined abstract equality function, then
+      --  issue a warning that Program_Error will be raised.
+
       -------------------------
       -- Build_Equality_Call --
       -------------------------
@@ -8409,6 +8414,27 @@ package body Exp_Ch4 is
              Unconstrained_UU_In_Component_List (Optional_Component_List);
       end Has_Unconstrained_UU_Component;
 
+      ---------------------------------------------
+      -- Warn_On_Abstract_Equality_For_Component --
+      ---------------------------------------------
+
+      procedure Warn_On_Abstract_Equality_For_Component
+        (Comp_Type : Entity_Id)
+      is
+         Eq : Entity_Id;
+      begin
+         if Is_Record_Type (Underlying_Type (Comp_Type)) then
+            Eq := Get_User_Defined_Equality (Comp_Type);
+
+            if Present (Eq) and then Is_Abstract_Subprogram (Eq) then
+               Error_Msg_Warn := SPARK_Mode /= On;
+               Error_Msg_NE ("call to abstract equality function of "
+                             & "component type &<<", N, Comp_Type);
+               Error_Msg_N ("\Program_Error [<<", N);
+            end if;
+         end if;
+      end Warn_On_Abstract_Equality_For_Component;
+
       --  Local variables
 
       Typl : Entity_Id;
@@ -8476,6 +8502,7 @@ package body Exp_Ch4 is
       --  Array types
 
       elsif Is_Array_Type (Typl) then
+         Warn_On_Abstract_Equality_For_Component (Component_Type (Typl));
 
          --  If we are doing full validity checking, and it is possible for the
          --  array elements to be invalid then expand out array comparisons to
@@ -8546,6 +8573,18 @@ package body Exp_Ch4 is
 
       elsif Is_Record_Type (Typl) then
 
+         declare
+            Comp : Entity_Id := First_Component (Typl);
+         begin
+            while Present (Comp) loop
+               if Chars (Comp) /= Name_uParent then
+                  Warn_On_Abstract_Equality_For_Component (Etype (Comp));
+               end if;
+
+               Next_Component (Comp);
+            end loop;
+         end;
+
          --  For tagged types, use the primitive "="
 
          if Is_Tagged_Type (Typl) then

Reply via email to