https://gcc.gnu.org/g:f1c22e6ea6e384ad07cb94dc20595de3e2b59e1d

commit r16-1876-gf1c22e6ea6e384ad07cb94dc20595de3e2b59e1d
Author: Javier Miranda <mira...@adacore.com>
Date:   Fri May 16 17:59:43 2025 +0000

    ada: Warn on untagged record type equality
    
    The frontend reports a warning when no component of an untagged
    record type U is a record type, and the type C of some of its
    components has defined its user-defined equality operator "=".
    
    The warning is reported because it may be surprising that, following
    RM 4.5.2 (24/3), the predefined "=" of the component type C takes
    precedence over its user-defined "=" when objects of the record
    type R are compared.
    
    gcc/ada/ChangeLog:
    
            * exp_ch3.adb (Build_Untagged_Record_Equality): Report the
            warning when no component of an untagged record type U is a
            record type, and the type C of some of its components has
            defined its user-defined equality operator "=".
            * exp_ch4.adb (Expand_Composite_Equality): Report the warning
            calling Warn_On_Ignored_Equality_Operator.
            * sem_warn.ads (Warn_On_Ignored_Equality_Operator): New subprogram.
            * sem_warn.adb (Warn_On_Ignored_Equality_Operator): Factorize code
            reporting the warning.

Diff:
---
 gcc/ada/exp_ch3.adb  | 28 ++++++++++++++++++++++++++++
 gcc/ada/exp_ch4.adb  | 15 +++++++--------
 gcc/ada/sem_warn.adb | 18 ++++++++++++++++++
 gcc/ada/sem_warn.ads |  9 +++++++++
 4 files changed, 62 insertions(+), 8 deletions(-)

diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index bdadac6cc137..4e2bef32a353 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -69,6 +69,7 @@ with Sem_Res;        use Sem_Res;
 with Sem_SCIL;       use Sem_SCIL;
 with Sem_Type;       use Sem_Type;
 with Sem_Util;       use Sem_Util;
+with Sem_Warn;       use Sem_Warn;
 with Sinfo;          use Sinfo;
 with Sinfo.Nodes;    use Sinfo.Nodes;
 with Sinfo.Utils;    use Sinfo.Utils;
@@ -77,6 +78,7 @@ with Snames;         use Snames;
 with Tbuild;         use Tbuild;
 with Ttypes;         use Ttypes;
 with Validsw;        use Validsw;
+with Warnsw;         use Warnsw;
 
 package body Exp_Ch3 is
 
@@ -5157,6 +5159,32 @@ package body Exp_Ch3 is
          if Is_Library_Level_Entity (Typ) then
             Set_Is_Public (Op);
          end if;
+
+      --  Otherwise, the result is defined in terms of the primitive equals
+      --  operator (RM 4.5.2 (24/3)). Report a warning if some component of
+      --  the untagged record has defined a user-defined "=", because it can
+      --  be surprising that the predefined "=" takes precedence over it.
+      --  This warning is not reported when Build_Eq is True because the
+      --  expansion of the built body will call Expand_Composite_Equality
+      --  that will report it if necessary.
+
+      elsif Warn_On_Ignored_Equality then
+         Comp := First_Component (Typ);
+
+         while Present (Comp) loop
+            if Present (User_Defined_Eq (Etype (Comp)))
+              and then not Is_Record_Type (Etype (Comp))
+              and then not Is_Intrinsic_Subprogram
+                             (User_Defined_Eq (Etype (Comp)))
+            then
+               Warn_On_Ignored_Equality_Operator
+                 (Typ      => Typ,
+                  Comp_Typ => Etype (Comp),
+                  Loc      => Sloc (User_Defined_Eq (Etype (Comp))));
+            end if;
+
+            Next_Component (Comp);
+         end loop;
       end if;
    end Build_Untagged_Record_Equality;
 
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index ce90f33aeda7..c9040bf5ba01 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -2470,21 +2470,20 @@ package body Exp_Ch4 is
 
          declare
             Op : constant Entity_Id := Find_Primitive_Eq (Comp_Type);
+
          begin
-            if Warn_On_Ignored_Equality
-              and then Present (Op)
+            if Present (Op)
               and then not In_Predefined_Unit (Base_Type (Comp_Type))
               and then not Is_Intrinsic_Subprogram (Op)
             then
                pragma Assert
                  (Is_First_Subtype (Outer_Type)
                    or else Is_Generic_Actual_Type (Outer_Type));
-               Error_Msg_Node_2 := Comp_Type;
-               Error_Msg_N
-                 ("?_q?""="" for type & uses predefined ""="" for }",
-                  Outer_Type);
-               Error_Msg_Sloc := Sloc (Op);
-               Error_Msg_N ("\?_q?""="" # is ignored here", Outer_Type);
+
+               Warn_On_Ignored_Equality_Operator
+                 (Typ      => Outer_Type,
+                  Comp_Typ => Comp_Type,
+                  Loc      => Sloc (Op));
             end if;
          end;
 
diff --git a/gcc/ada/sem_warn.adb b/gcc/ada/sem_warn.adb
index 32eee3370e26..156afc923075 100644
--- a/gcc/ada/sem_warn.adb
+++ b/gcc/ada/sem_warn.adb
@@ -3464,6 +3464,24 @@ package body Sem_Warn is
       end if;
    end Warn_On_Constant_Valid_Condition;
 
+   ---------------------------------------
+   -- Warn_On_Ignored_Equality_Operator --
+   ---------------------------------------
+
+   procedure Warn_On_Ignored_Equality_Operator
+     (Typ      : Entity_Id;
+      Comp_Typ : Entity_Id;
+      Loc      : Source_Ptr) is
+   begin
+      if Warn_On_Ignored_Equality then
+         Error_Msg_Node_2 := Comp_Typ;
+         Error_Msg_N ("?_q?""="" for type & uses predefined ""="" for }", Typ);
+
+         Error_Msg_Sloc := Loc;
+         Error_Msg_N ("\?_q?""="" # is ignored here", Typ);
+      end if;
+   end Warn_On_Ignored_Equality_Operator;
+
    -----------------------------
    -- Warn_On_Known_Condition --
    -----------------------------
diff --git a/gcc/ada/sem_warn.ads b/gcc/ada/sem_warn.ads
index edb872f3d976..3a347efa4b58 100644
--- a/gcc/ada/sem_warn.ads
+++ b/gcc/ada/sem_warn.ads
@@ -173,6 +173,15 @@ package Sem_Warn is
    --  Op assuming that its scalar operands are valid. Emit a warning when the
    --  result of the evaluation is True or False.
 
+   procedure Warn_On_Ignored_Equality_Operator
+     (Typ      : Entity_Id;
+      Comp_Typ : Entity_Id;
+      Loc      : Source_Ptr);
+   --  Typ is a composite type and Comp_Typ is the type of one of its
+   --  components. Output a warning notifying that the predefined "="
+   --  for Comp_Typ takes precedence over the user-defined equality
+   --  defined at the given location.
+
    procedure Warn_On_Known_Condition (C : Node_Id);
    --  C is a node for a boolean expression resulting from a relational
    --  or membership operation. If the expression has a compile time known

Reply via email to