The view conversion is constrained when its operand object is constrained.

Tested on x86-64/Linux, applied on the mainline.


2026-09-23  Eric Botcazou  <[email protected]>

        * exp_ch6.adb (Create_Extra_Actuals): Pass True for the extra actual
        of the Constrained attribute when the actual contains a conversion
        to a constrained subtype.
        * sem_res.adb (Resolve_Actuals): Skip the resolution of an actual
        that is a view conversion in fewer cases.  Remove redundant test.

-- 
Eric Botcazou
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index caa2e1e7d3c..d7749ae08ce 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -3156,8 +3156,10 @@ package body Exp_Ch6 is
                goto Skip_Extra_Actual_Generation;
 
             else
-               --  If the actual is a type conversion, then the constrained
-               --  test applies to the actual, not the target type.
+               --  If the actual is a type conversion and the target type is
+               --  constrained, then the view is constrained (RM 4.6(54)).
+               --  Otherwise, the test needs to be applied to the operand of
+               --  the conversion.
 
                declare
                   Act_Prev : Node_Id;
@@ -3170,6 +3172,9 @@ package body Exp_Ch6 is
                   while Nkind (Act_Prev) in N_Type_Conversion
                                           | N_Unchecked_Type_Conversion
                   loop
+                     exit when Nkind (Act_Prev) = N_Type_Conversion
+                       and then Is_Constrained (Etype (Act_Prev));
+
                      Act_Prev := Expression (Act_Prev);
                   end loop;
 
@@ -3187,6 +3192,11 @@ package body Exp_Ch6 is
                        (Expr => New_Occurrence_Of (Standard_False, Loc),
                         EF   => Extra_Constrained (Formal));
 
+                  elsif Nkind (Act_Prev) = N_Type_Conversion then
+                     Add_Extra_Actual
+                       (Expr => New_Occurrence_Of (Standard_True, Loc),
+                        EF   => Extra_Constrained (Formal));
+
                   else
                      Add_Extra_Actual
                        (Expr =>
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index 078e32c42a1..fe39ba3f9c6 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -4350,23 +4350,24 @@ package body Sem_Res is
                end if;
             end if;
 
-            --  If the formal is Out or In_Out, do not resolve and expand the
-            --  conversion, because it is subsequently expanded into explicit
-            --  temporaries and assignments. However, the object of the
-            --  conversion can be resolved. An exception is the case of tagged
-            --  type conversion with a class-wide actual. In that case we want
-            --  the tag check to occur and no temporary will be needed (no
-            --  representation change can occur) and the parameter is passed by
-            --  reference, so we go ahead and resolve the type conversion.
-            --  Another exception is the case of reference to component or
-            --  subcomponent of a bit-packed array, in which case we want to
-            --  defer expansion to the point the in and out assignments are
-            --  performed.
+            --  If the formal is Out or In Out, do not resolve and expand a
+            --  type conversion if it is to an elementary type, or an array
+            --  type, or if it involves a change of representation, because
+            --  it will be subsequently expanded into explicit temporaries
+            --  and assignments (see Exp_Ch6.Expand_Actuals). However, the
+            --  expression of the conversion needs to be resolved, except
+            --  in the case of a reference to a component or subcomponent
+            --  of a bit-packed array, in which case we want to defer the
+            --  expansion to the point the assignments are performed.
 
             if Ekind (F) /= E_In_Parameter
               and then Nkind (A) = N_Type_Conversion
-              and then not Is_Class_Wide_Type (Etype (Expression (A)))
-              and then not Is_Interface (Etype (A))
+              and then (Is_Elementary_Type (Etype (A))
+                         or else Is_Array_Type (Etype (A))
+                         or else not
+                           Has_Compatible_Representation
+                             (Target_Typ  => Etype (A),
+                              Operand_Typ => Etype (Expression (A))))
             then
                declare
                   Expr_Typ : constant Entity_Id := Etype (Expression (A));
@@ -4374,9 +4375,7 @@ package body Sem_Res is
                begin
                   --  Check RM 4.6 (24.2/2)
 
-                  if Is_Array_Type (Etype (F))
-                    and then Is_View_Conversion (A)
-                  then
+                  if Is_Array_Type (Etype (F)) then
                      --  In a view conversion, the conversion must be legal in
                      --  both directions, and thus both component types must be
                      --  aliased, or neither (4.6 (8)).

Reply via email to