]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ada: Missing contract checks for calls to formal subprograms within instances
authorGary Dismukes <dismukes@adacore.com>
Thu, 15 Jan 2026 20:40:28 +0000 (20:40 +0000)
committerMarc Poulhiès <dkm@gcc.gnu.org>
Mon, 25 May 2026 08:28:10 +0000 (10:28 +0200)
While working on a visibility bug, it was noticed that preconditions
on formal subprograms are not being checked on calls to the subprograms
within package instantiations.  The wrapper subprogram that is created to
perform the check (and invoke the actual subprogram) was not being used
as the target of calls, and the actual subprogram is being called instead
(bypassing the check).  This was due to the subprogram renaming created
(for the actual-to-formal association) and the wrapper being homographs,
and the loop over interpretations in Collect_Interps happening to resolve
calls to the actual instead of the wrapper.  This wrong resolution is
avoided by removing the homographic subprogram renaming, so that the
resolution can only resolve to the wrapper (which will only include
the precondition check in the case where assertions are enabled).

gcc/ada/ChangeLog:

* sem_ch12.adb (Build_Subprogram_Wrapper): Remove the subprogram
renaming created for the formal-to-actual association from the
list of renamings (only when such a subprogram renaming is present).
Also, change the name from plural to singular, since the procedure
only creates one wrapper, update the spec comment to reflect that,
and clarify the state and use of the Renamings parameter.

gcc/ada/sem_ch12.adb

index 8b81a0e34eeacf43e808effe4cbad49f16530e5c..a1afb17bd77909095ad1c93a0abf8526805b8c48 100644 (file)
@@ -523,21 +523,28 @@ package body Sem_Ch12 is
    --  The body of the wrapper is a call to the actual, with the generated
    --  pre/postconditon checks added.
 
-   procedure Build_Subprogram_Wrappers
+   procedure Build_Subprogram_Wrapper
      (Match             : Node_Id;
       Analyzed_Formal   : Node_Id;
       Unanalyzed_Formal : Node_Id;
       Renamings         : List_Id);
    --  Ada 2022: AI12-0272 introduces pre/postconditions for formal
    --  subprograms. The implementation of making the formal into a renaming
-   --  of the actual does not work, given that subprogram renaming cannot
-   --  carry aspect specifications. Instead we must create subprogram
-   --  wrappers whose body is a call to the actual, and whose declaration
+   --  of the actual does not work, given that subprogram renaming cannot
+   --  carry aspect specifications. Instead we must create subprogram
+   --  wrapper whose body is a call to the actual, and whose declaration
    --  carries the aspects of the formal.
-   --  The wrapper declaration and body are appended to Renamings.
    --  ???But renaming declarations CAN have aspects specs,
    --  and that was true from the start (see AI05-0183-1).
    --
+   --  Renamings is a list of the declarations created to represent the
+   --  parameter associations of the instantiation, and the last element
+   --  will generally be a subprogram renaming of the actual subprogram
+   --  (though it can also be a generated subprogram body in some cases,
+   --  such as when a formal procedure defaults to "null"). The wrapper
+   --  declaration and body are appended to Renamings, substituting for
+   --  the last element in the subprogram renaming case.
+   --
    --  The procedure also copies the aspect specifications from the unanalyzed
    --  formal subprogram to the wrapper subprogram for later analysis in the
    --  context of the instantiation.
@@ -2757,7 +2764,7 @@ package body Sem_Ch12 is
                if Has_Contracts (Assoc.An_Formal)
                  and then (Expander_Active or GNATprove_Mode)
                then
-                  Build_Subprogram_Wrappers
+                  Build_Subprogram_Wrapper
                     (Match             => Match,
                      Analyzed_Formal   => Assoc.An_Formal,
                      Unanalyzed_Formal => Assoc.Un_Formal,
@@ -7538,11 +7545,11 @@ package body Sem_Ch12 is
       return Body_Node;
    end Build_Subprogram_Body_Wrapper;
 
-   -------------------------------
-   -- Build_Subprogram_Wrappers --
-   -------------------------------
+   ------------------------------
+   -- Build_Subprogram_Wrapper --
+   ------------------------------
 
-   procedure Build_Subprogram_Wrappers
+   procedure Build_Subprogram_Wrapper
      (Match             : Node_Id;
       Analyzed_Formal   : Node_Id;
       Unanalyzed_Formal : Node_Id;
@@ -7571,7 +7578,7 @@ package body Sem_Ch12 is
       Decl_Node   : Node_Id;
       Actual_Name : Node_Id;
 
-   --  Start of processing for Build_Subprogram_Wrappers
+   --  Start of processing for Build_Subprogram_Wrapper
 
    begin
       --  Create declaration for wrapper subprogram.
@@ -7617,6 +7624,18 @@ package body Sem_Ch12 is
          Next (Aspect_Spec);
       end loop;
 
+      --  Remove the subprogram renaming declaration, which will be replaced
+      --  by the wrapper subprogram (we don't want two homographs in the same
+      --  scope, and the renaming will be overridden by the wrapper). We test
+      --  that the actual is present and not defaulted, and in the latter case
+      --  we don't remove the declaration, which may be an internal subprogram
+      --  body rather than a renaming (such as created for a "null" default),
+      --  and that body must be kept.
+
+      if Is_Entity_Name (Match) then
+         Remove (Last (Renamings));
+      end if;
+
       Append_To (Renamings, Decl_Node);
 
       --  Create corresponding body, and append it to association list
@@ -7626,7 +7645,7 @@ package body Sem_Ch12 is
 
       Append_To (Renamings,
         Build_Subprogram_Body_Wrapper (Formal, Actual_Name));
-   end Build_Subprogram_Wrappers;
+   end Build_Subprogram_Wrapper;
 
    -------------------------------------------
    -- Build_Instance_Compilation_Unit_Nodes --