[COMMITTED,01/35] ada: Pass parameters of full access unconstrained array types by copy in calls

Message ID 20241025091107.485741-1-poulhies@adacore.com
State Committed
Commit 1c298fc41512a1062f348eb54d54d01697a66ffc
Headers
Series [COMMITTED,01/35] ada: Pass parameters of full access unconstrained array types by copy in calls |

Commit Message

Marc Poulhiès Oct. 25, 2024, 9:10 a.m. UTC
  From: Eric Botcazou <ebotcazou@adacore.com>

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.

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

---
 gcc/ada/exp_ch6.adb | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)
  

Patch

diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index c868234655e..c550b1c8c1f 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -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;