]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ada: Pass parameters of full access unconstrained array types by copy in calls
authorEric Botcazou <ebotcazou@adacore.com>
Thu, 12 Sep 2024 14:11:47 +0000 (16:11 +0200)
committerMarc Poulhiès <dkm@gcc.gnu.org>
Fri, 25 Oct 2024 09:08:59 +0000 (11:08 +0200)
When a full access array type is declared, either Volatile_Full_Access in
Ada 2012 or Atomic in Ada 2022, an implicit base array type is built by the
compiler with the Full_Access flag set, although full accesses cannot be
generated for objects of this type because the size is not known statically.

If the component type is a record with default values, an initialization
procedure taking a parameter of the base array type is built. Given that
full accesses cannot be generated for the parameter inside the procedure,
we need to pass the actual parameter by copy to the procedure in order to
implement the full access semantics.

gcc/ada/ChangeLog:

* exp_ch6.adb (Expand_Actuals.Is_Legal_Copy): Return True for an
initialization procedure with a full access formal parameter.
(Expand_Actuals.Requires_Atomic_Or_Volatile_Copy): Return True if
the formal parameter is of a full access unconstrained array type.

gcc/ada/exp_ch6.adb

index c868234655ea861e216f1ae2beee8e04c6ef41a9..c550b1c8c1f08601eafb30b6b6e7928dd794dc55 100644 (file)
@@ -1613,7 +1613,8 @@ package body Exp_Ch6 is
 
       function Requires_Atomic_Or_Volatile_Copy return Boolean;
       --  Returns whether a copy is required as per RM C.6(19) and gives a
-      --  warning in this case.
+      --  warning in this case. This also handles the special case of a base
+      --  array type with full access semantics.
 
       ---------------------------
       -- Add_Call_By_Copy_Code --
@@ -2269,15 +2270,22 @@ package body Exp_Ch6 is
 
       function Is_Legal_Copy return Boolean is
       begin
-         --  An attempt to copy a value of such a type can only occur if
-         --  representation clauses give the actual a misaligned address.
+         --  Calls to the initialization procedure of full access types may
+         --  require a copy in order to implement the full access semantics.
 
-         if Is_By_Reference_Type (Etype (Formal))
+         if Is_Init_Proc (Subp) and then Is_Full_Access (Etype (Formal)) then
+            return True;
+
+         --  In the other cases, a copy is not allowed for by-reference types
+         --  or if the parameter is aliased or explicitly passed by reference.
+
+         elsif Is_By_Reference_Type (Etype (Formal))
            or else Is_Aliased (Formal)
            or else (Mechanism (Formal) = By_Reference
                      and then not Has_Foreign_Convention (Subp))
          then
-
+            --  An attempt to copy a value of such types can only occur if
+            --  representation clauses give the actual a misaligned address.
             --  The actual may in fact be properly aligned but there is not
             --  enough front-end information to determine this. In that case
             --  gigi will emit an error or a warning if a copy is not legal,
@@ -2386,6 +2394,15 @@ package body Exp_Ch6 is
             return True;
          end if;
 
+         --  Special case for the base type of a full access array type: full
+         --  access semantics cannot be enforced for the base type inside the
+         --  called subprogram so we do it at the call site by means of a copy.
+
+         if Ekind (E_Formal) = E_Array_Type and then Is_Full_Access (E_Formal)
+         then
+            return True;
+         end if;
+
          return False;
       end Requires_Atomic_Or_Volatile_Copy;