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

commit r15-4898-ge2f073947a324bbfee866d9282bb778ddead95f4
Author: Bob Duff <d...@adacore.com>
Date:   Wed Oct 9 07:25:14 2024 -0400

    ada: Correction to disable self-referential with_clauses
    
    Follow-on to previous change "Disable self-referential with_clauses",
    which caused some regressions. Remove useless use clauses referring
    to useless self-referential with'ed packages. This is necessary
    because in some cases, such use clauses cause the compiler to
    crash or give spurious errors.
    
    In addition, enable the warning on self-referential with_clauses.
    
    gcc/ada/ChangeLog:
    
            * sem_ch10.adb (Analyze_With_Clause): In the case of a
            self-referential with clause, if there is a subsequent use clause
            for the same package (which is necessarily useless), remove it from
            the context clause. Reenable the warning.

Diff:
---
 gcc/ada/sem_ch10.adb | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb
index 202a44eb87c1..4e582440c40c 100644
--- a/gcc/ada/sem_ch10.adb
+++ b/gcc/ada/sem_ch10.adb
@@ -3039,11 +3039,32 @@ package body Sem_Ch10 is
 
          --  Self-referential withs are always useless, so warn
 
-         if Warn_On_Redundant_Constructs and then False then -- ???
-            --  Disable for now, because it breaks SPARK builds
+         if Warn_On_Redundant_Constructs then
             Error_Msg_N ("unnecessary with of self?r?", N);
          end if;
 
+         declare
+            This : Node_Id := Next (N);
+         begin
+            --  Remove subsequent use clauses for the same package
+
+            while Present (This) loop
+               declare
+                  Nxt : constant Node_Id := Next (This);
+               begin
+                  if Nkind (This) = N_Use_Package_Clause
+                    and then Same_Name (Name (N), Name (This))
+                  then
+                     if not More_Ids (This) and not Prev_Ids (This) then
+                        Remove (This);
+                     end if;
+                  end if;
+
+                  This := Nxt;
+               end;
+            end loop;
+         end;
+
       --  Normal (non-self-referential) case
 
       else

Reply via email to