diff mbox series

[COMMITTED,09/38] ada: Correction to disable self-referential with_clauses

Message ID 20241104161116.1431659-9-poulhies@adacore.com
State New
Headers show
Series [COMMITTED,01/38] ada: Fix asymmetry in resolution of unary intrinsic operators | expand

Commit Message

Marc Poulhiès Nov. 4, 2024, 4:10 p.m. UTC
From: Bob Duff <duff@adacore.com>

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.

Tested on x86_64-pc-linux-gnu, committed on master.

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

Patch

diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb
index 202a44eb87c..4e582440c40 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