When the type of a scalar formal parameter of mode out has the
Default_Value aspect, the actual type is also required to have that
aspect (required now by AI12-0074, RM 6.4.1(5.3/4)), and the value of
the actual must be passed on calls (since the actual is guaranteed to be
initialized and deinitialization must be prevented in case the formal is
never assigned to). This was already working for simple cases, but was
not supported properly when the actual is a view conversion. The
compiler now initializes the temp created for such out parameters from
the result of converting the view conversion's operand to the formal's
base type.

Tested on x86_64-pc-linux-gnu, committed on trunk

2020-06-15  Gary Dismukes  <dismu...@adacore.com>

gcc/ada/

        * exp_ch6.adb (Add_Call_By_Copy_Code): In the case of a view
        conversion passed to a scalar out-mode parameter where the
        formal has Default_Value set, declare the copy temp with the
        base type of the formal's subtype and initialize the copy temp
        with the actual's value.
--- gcc/ada/exp_ch6.adb
+++ gcc/ada/exp_ch6.adb
@@ -1446,6 +1446,25 @@ package body Exp_Ch6 is
          then
             Init := New_Occurrence_Of (Var, Loc);
 
+         --  View conversions when the formal type has the Default_Value aspect
+         --  require passing in the value of the conversion's operand. The type
+         --  of that operand also has Default_Value, as required by AI12-0074
+         --  (RM 6.4.1(5.3/4)). The subtype denoted by the subtype_indication
+         --  is changed to the base type of the formal subtype, to ensure that
+         --  the actual's value can be assigned without a constraint check
+         --  (note that no check is done on passing to an out parameter). Also
+         --  note that the two types necessarily share the same ancestor type,
+         --  as required by 6.4.1(5.2/4), so underlying base types will match.
+
+         elsif Ekind (Formal) = E_Out_Parameter
+           and then Is_Scalar_Type (Etype (F_Typ))
+           and then Nkind (Actual) = N_Type_Conversion
+           and then Present (Default_Aspect_Value (Etype (F_Typ)))
+         then
+            Indic := New_Occurrence_Of (Base_Type (F_Typ), Loc);
+            Init  := Convert_To
+                       (Base_Type (F_Typ), New_Occurrence_Of (Var, Loc));
+
          else
             Init := Empty;
          end if;

Reply via email to