public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/c++-coroutines] [Ada] Additional warnings on overlapping actuals of composite types
@ 2020-06-11 20:07 Iain D Sandoe
  0 siblings, 0 replies; 2+ messages in thread
From: Iain D Sandoe @ 2020-06-11 20:07 UTC (permalink / raw)
  To: gcc-cvs

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

commit eb85899d605dcfc4519bf764959d92672f0f0749
Author: Ed Schonberg <schonberg@adacore.com>
Date:   Mon Mar 16 11:25:14 2020 -0400

    [Ada] Additional warnings on overlapping actuals of composite types
    
    2020-06-11  Ed Schonberg  <schonberg@adacore.com>
    
    gcc/ada/
    
            * sem_warn.adb (Warn_On_Overlapping_Actuals): Simplify code,
            remove inner predicate Is_Covered_Formal, preserve warning for
            two overlapping composite types when only one is writable, and
            for two overlapping and writable elementary types.

Diff:
---
 gcc/ada/sem_warn.adb | 247 ++++++++++++++++++++++++++++-----------------------
 1 file changed, 138 insertions(+), 109 deletions(-)

diff --git a/gcc/ada/sem_warn.adb b/gcc/ada/sem_warn.adb
index 3fe77b077bc..9a4a4d05f2f 100644
--- a/gcc/ada/sem_warn.adb
+++ b/gcc/ada/sem_warn.adb
@@ -3643,9 +3643,6 @@ package body Sem_Warn is
    ---------------------------------
 
    procedure Warn_On_Overlapping_Actuals (Subp : Entity_Id; N : Node_Id) is
-      function Is_Covered_Formal (Formal : Node_Id) return Boolean;
-      --  Return True if Formal is covered by the rule
-
       function Refer_Same_Object
         (Act1 : Node_Id;
          Act2 : Node_Id) return Boolean;
@@ -3657,19 +3654,6 @@ package body Sem_Warn is
       --  object_name is known to refer to the same object as the other name
       --  (RM 6.4.1(6.11/3))
 
-      -----------------------
-      -- Is_Covered_Formal --
-      -----------------------
-
-      function Is_Covered_Formal (Formal : Node_Id) return Boolean is
-      begin
-         return
-           Ekind_In (Formal, E_Out_Parameter, E_In_Out_Parameter)
-             and then (Is_Elementary_Type (Etype (Formal))
-                        or else Is_Record_Type (Etype (Formal))
-                        or else Is_Array_Type (Etype (Formal)));
-      end Is_Covered_Formal;
-
       -----------------------
       -- Refer_Same_Object --
       -----------------------
@@ -3759,137 +3743,182 @@ package body Sem_Warn is
       Form1 := First_Formal (Subp);
       Act1  := First_Actual (N);
       while Present (Form1) and then Present (Act1) loop
-         if Is_Covered_Formal (Form1)
-            or else not Is_Elementary_Type (Etype (Act1))
+         if Is_Generic_Type (Etype (Act1)) then
+            return;
+         end if;
+
+         --  One of the formals must be either (in)-out or composite.
+         --  The other must be (in)-out.
+
+         if Is_Elementary_Type (Etype (Act1))
+           and then Ekind (Form1) = E_In_Parameter
          then
+            null;
+
+         else
             Form2 := First_Formal (Subp);
             Act2  := First_Actual (N);
             while Present (Form2) and then Present (Act2) loop
                if Form1 /= Form2
-                 and then Is_Covered_Formal (Form2)
                  and then Refer_Same_Object (Act1, Act2)
                then
-                  --  Guard against previous errors
+                  if Is_Generic_Type (Etype (Act2)) then
+                     return;
+                  end if;
 
-                  if Error_Posted (N)
-                    or else No (Etype (Act1))
-                    or else No (Etype (Act2))
-                  then
-                     null;
+                  --  First case : two writable elementary parameters
+                  --  that overlap.
 
-                  --  If the actual is a function call in prefix notation,
-                  --  there is no real overlap.
+                  if (Is_Elementary_Type (Etype (Form1))
+                    and then Is_Elementary_Type (Etype (Form2))
+                    and then Ekind (Form1) /= E_In_Parameter
+                    and then Ekind (Form2) /= E_In_Parameter)
 
-                  elsif Nkind (Act2) = N_Function_Call then
-                     null;
+                  --  Second case : two composite parameters that overlap,
+                  --  one of which is writable.
 
-                  --  If type is not by-copy, assume that aliasing is intended
+                    or else (Is_Composite_Type (Etype (Form1))
+                     and then Is_Composite_Type (Etype (Form2))
+                     and then (Ekind (Form1) /= E_In_Parameter
+                       or else Ekind (Form2) /= E_In_Parameter))
 
-                  elsif
-                    Present (Underlying_Type (Etype (Form1)))
-                      and then
-                        (Is_By_Reference_Type (Underlying_Type (Etype (Form1)))
-                          or else
-                            Convention (Underlying_Type (Etype (Form1))) =
-                                              Convention_Ada_Pass_By_Reference)
-                  then
-                     null;
+                  --  Third case : an elementary writable parameter that
+                  --  overlaps a composite one.
 
-                  --  Under Ada 2012 we only report warnings on overlapping
-                  --  arrays and record types if switch is set.
+                    or else (Is_Elementary_Type (Etype (Form1))
+                     and then Ekind (Form1) /= E_In_Parameter
+                     and then Is_Composite_Type (Etype (Form2)))
 
-                  elsif Ada_Version >= Ada_2012
-                    and then not Is_Elementary_Type (Etype (Form1))
-                    and then not Warn_On_Overlap
+                   or else (Is_Elementary_Type (Etype (Form2))
+                     and then Ekind (Form2) /= E_In_Parameter
+                     and then Is_Composite_Type (Etype (Form1)))
                   then
-                     null;
 
-                  --  Here we may need to issue overlap message
+                  --  Guard against previous errors
 
-                  else
-                     Error_Msg_Warn :=
+                     if Error_Posted (N)
+                       or else No (Etype (Act1))
+                       or else No (Etype (Act2))
+                     then
+                        null;
 
-                       --  Overlap checking is an error only in Ada 2012. For
-                       --  earlier versions of Ada, this is a warning.
+                     --  If the actual is a function call in prefix notation,
+                     --  there is no real overlap.
 
-                       Ada_Version < Ada_2012
+                     elsif Nkind (Act2) = N_Function_Call then
+                        null;
 
-                       --  Overlap is only illegal in Ada 2012 in the case of
-                       --  elementary types (passed by copy). For other types,
-                       --  we always have a warning in all Ada versions.
+                     --  If type is explicitly not by-copy, assume that
+                     --  aliasing is intended.
+
+                     elsif
+                       Present (Underlying_Type (Etype (Form1)))
+                         and then
+                           (Is_By_Reference_Type
+                             (Underlying_Type (Etype (Form1)))
+                             or else
+                               Convention (Underlying_Type (Etype (Form1))) =
+                                            Convention_Ada_Pass_By_Reference)
+                     then
+                        null;
 
-                       or else not Is_Elementary_Type (Etype (Form1))
+                     --  Under Ada 2012 we only report warnings on overlapping
+                     --  arrays and record types if switch is set.
 
-                       --  debug flag -gnatd.E changes the error to a warning
-                       --  even in Ada 2012 mode.
+                     elsif Ada_Version >= Ada_2012
+                       and then not Is_Elementary_Type (Etype (Form1))
+                       and then not Warn_On_Overlap
+                     then
+                        null;
 
-                       or else Error_To_Warning
-                       or else Warn_Only;
+                     --  Here we may need to issue overlap message
 
-                     declare
-                        Act  : Node_Id;
-                        Form : Entity_Id;
+                     else
+                        Error_Msg_Warn :=
 
-                     begin
-                        --  Find matching actual
+                          --  Overlap checking is an error only in Ada 2012.
+                          --  For earlier versions of Ada, this is a warning.
 
-                        Act  := First_Actual (N);
-                        Form := First_Formal (Subp);
-                        while Act /= Act2 loop
-                           Next_Formal (Form);
-                           Next_Actual (Act);
-                        end loop;
+                          Ada_Version < Ada_2012
 
-                        if Is_Elementary_Type (Etype (Act1))
-                          and then Ekind (Form2) = E_In_Parameter
-                        then
-                           null;  --  No real aliasing
+                          --  Overlap is only illegal in Ada 2012 in the case
+                          --  of elementary types (passed by copy). For other
+                          --  types we always have a warning in all versions.
 
-                        elsif Is_Elementary_Type (Etype (Act2))
-                          and then Ekind (Form2) = E_In_Parameter
-                        then
-                           null;  --  Ditto
+                          or else not Is_Elementary_Type (Etype (Form1))
 
-                        --  If the call was written in prefix notation, and
-                        --  thus its prefix before rewriting was a selected
-                        --  component, count only visible actuals in the call.
+                          --  debug flag -gnatd.E changes the error to a
+                          --  warning even in Ada 2012 mode.
 
-                        elsif Is_Entity_Name (First_Actual (N))
-                          and then Nkind (Original_Node (N)) = Nkind (N)
-                          and then Nkind (Name (Original_Node (N))) =
-                                                         N_Selected_Component
-                          and then
-                            Is_Entity_Name (Prefix (Name (Original_Node (N))))
-                          and then
-                            Entity (Prefix (Name (Original_Node (N)))) =
-                              Entity (First_Actual (N))
-                        then
-                           if Act1 = First_Actual (N) then
-                              Error_Msg_FE
-                                ("<<`IN OUT` prefix overlaps with "
-                                 & "actual for&", Act1, Form);
+                          or else Error_To_Warning
+                          or else Warn_Only;
+
+                        declare
+                           Act  : Node_Id;
+                           Form : Entity_Id;
+
+                        begin
+                           --  Find matching actual
+
+                           Act  := First_Actual (N);
+                           Form := First_Formal (Subp);
+                           while Act /= Act2 loop
+                              Next_Formal (Form);
+                              Next_Actual (Act);
+                           end loop;
+
+                           if Is_Elementary_Type (Etype (Act1))
+                             and then Ekind (Form2) = E_In_Parameter
+                           then
+                              null;  --  No real aliasing
+
+                           elsif Is_Elementary_Type (Etype (Act2))
+                             and then Ekind (Form2) = E_In_Parameter
+                           then
+                              null;  --  Ditto
+
+                           --  If the call was written in prefix notation, and
+                           --  thus its prefix before rewriting was a selected
+                           --  component, count only visible actuals in call.
+
+                           elsif Is_Entity_Name (First_Actual (N))
+                             and then Nkind (Original_Node (N)) = Nkind (N)
+                             and then Nkind (Name (Original_Node (N))) =
+                                                           N_Selected_Component
+                             and then
+                               Is_Entity_Name
+                                 (Prefix (Name (Original_Node (N))))
+                             and then
+                               Entity (Prefix (Name (Original_Node (N)))) =
+                                 Entity (First_Actual (N))
+                           then
+                              if Act1 = First_Actual (N) then
+                                 Error_Msg_FE
+                                   ("<<`IN OUT` prefix overlaps with "
+                                    & "actual for&", Act1, Form);
+
+                              else
+                                 --  For greater clarity, give name of formal
+
+                                 Error_Msg_Node_2 := Form;
+                                 Error_Msg_FE
+                                   ("<<writable actual for & overlaps with "
+                                    & "actual for&", Act1, Form);
+                              end if;
 
                            else
                               --  For greater clarity, give name of formal
 
                               Error_Msg_Node_2 := Form;
+
+                              --  This is one of the messages
+
                               Error_Msg_FE
                                 ("<<writable actual for & overlaps with "
-                                 & "actual for&", Act1, Form);
+                                 & "actual for&", Act1, Form1);
                            end if;
-
-                        else
-                           --  For greater clarity, give name of formal
-
-                           Error_Msg_Node_2 := Form;
-
-                           --  This is one of the messages
-
-                           Error_Msg_FE
-                             ("<<writable actual for & overlaps with "
-                              & "actual for&", Act1, Form1);
-                        end if;
-                     end;
+                        end;
+                     end if;
                   end if;
 
                   return;


^ permalink raw reply	[flat|nested] 2+ messages in thread

* [gcc/devel/c++-coroutines] [Ada] Additional warnings on overlapping actuals of composite types
@ 2020-06-10 23:26 Iain D Sandoe
  0 siblings, 0 replies; 2+ messages in thread
From: Iain D Sandoe @ 2020-06-10 23:26 UTC (permalink / raw)
  To: gcc-cvs

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

commit f95fb9d019147b2af0c8107d6c6a6e2b6034d9fe
Author: Ed Schonberg <schonberg@adacore.com>
Date:   Mon Mar 9 16:36:55 2020 -0400

    [Ada] Additional warnings on overlapping actuals of composite types
    
    2020-06-10  Ed Schonberg  <schonberg@adacore.com>
    
    gcc/ada/
    
            * sem_warn.adb (Warn_On_Overlapping_Actuals): Add a warning when
            two actuals in a call overlap, both are composite types that may
            be passed by reference, and only one of them is writable.

Diff:
---
 gcc/ada/sem_warn.adb | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/gcc/ada/sem_warn.adb b/gcc/ada/sem_warn.adb
index b84e82e989a..a3195a19369 100644
--- a/gcc/ada/sem_warn.adb
+++ b/gcc/ada/sem_warn.adb
@@ -3742,10 +3742,26 @@ package body Sem_Warn is
       --  If appropriate warning switch is set, we also report warnings on
       --  overlapping parameters that are record types or array types.
 
+      --  It is also worthwhile to warn on overlaps of composite objects when
+      --  only one of the formals is (in)-out.  Note that the RM rule above is
+      --  a legality rule. We choose to implement this check as a warning to
+      --  avoid major incompatibilities with legacy code. We exclude internal
+      --  sources from the warning, because subprograms in Container libraries
+      --  would be affected by the warning.
+
+      --  Note also that the rule in 6.4.1 (6.17/3), introduced by AI12-0324,
+      --  is potentially more expensive to verify, and is not yet implemented.
+
+      if Is_Internal_Unit (Current_Sem_Unit) then
+         return;
+      end if;
+
       Form1 := First_Formal (Subp);
       Act1  := First_Actual (N);
       while Present (Form1) and then Present (Act1) loop
-         if Is_Covered_Formal (Form1) then
+         if Is_Covered_Formal (Form1)
+            or else not Is_Elementary_Type (Etype (Act1))
+         then
             Form2 := First_Formal (Subp);
             Act2  := First_Actual (N);
             while Present (Form2) and then Present (Act2) loop


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-06-11 20:07 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-11 20:07 [gcc/devel/c++-coroutines] [Ada] Additional warnings on overlapping actuals of composite types Iain D Sandoe
  -- strict thread matches above, loose matches on Subject: below --
2020-06-10 23:26 Iain D Sandoe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).