]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Ada: Reject formal parameter as name of subprogram renaming
authorEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 30 Dec 2025 10:44:54 +0000 (11:44 +0100)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 30 Dec 2025 11:06:07 +0000 (12:06 +0100)
This implements a minimal form of the old RM 8.5.4(6) rule, which forbids
the use of (the name of) a formal parameter of the specification in the
name of a renaming subprogram declaration; it turns out that implementing
the full rule breaks existing code that works fine otherwise.

gcc/ada/
PR ada/15605
* sem_ch8.adb (Analyze_Subprogram_Renaming): Give an error if the
name is also that of a formal parameter of the specification.

gcc/testsuite/
* gnat.dg/specs/profile1.ads: New test.

gcc/ada/sem_ch8.adb
gcc/testsuite/gnat.dg/specs/profile1.ads [new file with mode: 0644]

index 11f2b19b0b0e5317bb85566832e2e134a2612631..8f534af7e1b4e405a9224feefbd9ae82306ab7f5 100644 (file)
@@ -3678,13 +3678,34 @@ package body Sem_Ch8 is
       then
          --  Do not mention the renaming if it comes from an instance
 
-         if not Is_Actual then
-            Error_Msg_N ("expect valid subprogram name in renaming", N);
-         else
+         if Is_Actual then
             Error_Msg_NE ("no visible subprogram for formal&", N, Nam);
+         else
+            Error_Msg_N ("expect valid subprogram name in renaming", N);
          end if;
 
          return;
+
+      --  RM 8.5.4(6): A name that denotes a formal parameter of the subprogram
+      --  specification is not allowed within Nam. But this was not enforced by
+      --  GNAT historically, so we restrict it to direct names.
+
+      elsif Nkind (Nam) = N_Identifier and then not Is_Actual then
+         declare
+            F : Node_Id;
+
+         begin
+            F := First_Formal (New_S);
+            while Present (F) loop
+               if Chars (F) = Chars (Nam) then
+                  Error_Msg_NE
+                    ("formal parameter& cannot be used in renaming", N, F);
+                  return;
+               end if;
+
+               Next_Formal (F);
+            end loop;
+         end;
       end if;
 
       --  Find the renamed entity that matches the given specification. Disable
diff --git a/gcc/testsuite/gnat.dg/specs/profile1.ads b/gcc/testsuite/gnat.dg/specs/profile1.ads
new file mode 100644 (file)
index 0000000..1caa5f0
--- /dev/null
@@ -0,0 +1,12 @@
+-- PR ada/15605
+-- { dg-do compile }
+
+package Profile1 is
+
+  subtype Int is Integer;
+  function F (Int : Integer) return Int; -- { dg-error "formal parameter" }
+
+  procedure Foo (X : Integer);
+  procedure P (Foo : Integer) renames Foo; -- { dg-error "formal parameter" }
+
+end Profile1;