[COMMITTED,01/35] ada: Pass parameters of full access unconstrained array types by copy in calls
Commit Message
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(-)
@@ -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;