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 Botcazoudiff --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)).