===================================================================
@@ -4698,6 +4698,10 @@
-- end loop;
-- end;
+ -- In addition, if the loop specification is given by a subtype
+ -- indication that constrains a predicated type, the bounds of
+ -- iteration are given by those of the subtype indication.
+
else
Static_Predicate : declare
S : Node_Id;
@@ -4706,6 +4710,11 @@
Alts : List_Id;
Cstm : Node_Id;
+ -- If the domain is an itype, note the bounds of its range.
+
+ L_Hi : Node_Id;
+ L_Lo : Node_Id;
+
function Lo_Val (N : Node_Id) return Node_Id;
-- Given static expression or static range, returns an identifier
-- whose value is the low bound of the expression value or range.
@@ -4760,6 +4769,11 @@
Set_Warnings_Off (Loop_Id);
+ if Is_Itype (Ltype) then
+ L_Hi := High_Bound (Scalar_Range (Ltype));
+ L_Lo := Low_Bound (Scalar_Range (Ltype));
+ end if;
+
-- Loop to create branches of case statement
Alts := New_List;
@@ -4768,12 +4782,21 @@
-- Initial value is largest value in predicate.
- D :=
- Make_Object_Declaration (Loc,
- Defining_Identifier => Loop_Id,
- Object_Definition => New_Occurrence_Of (Ltype, Loc),
- Expression => Hi_Val (Last (Stat)));
+ if Is_Itype (Ltype) then
+ D :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Loop_Id,
+ Object_Definition => New_Occurrence_Of (Ltype, Loc),
+ Expression => L_Hi);
+ else
+ D :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Loop_Id,
+ Object_Definition => New_Occurrence_Of (Ltype, Loc),
+ Expression => Hi_Val (Last (Stat)));
+ end if;
+
P := Last (Stat);
while Present (P) loop
if No (Prev (P)) then
@@ -4794,15 +4817,34 @@
Prev (P);
end loop;
+ if Is_Itype (Ltype)
+ and then Is_OK_Static_Expression (L_Lo)
+ and then
+ Expr_Value (L_Lo) /= Expr_Value (Lo_Val (First (Stat)))
+ then
+ Append_To (Alts,
+ Make_Case_Statement_Alternative (Loc,
+ Statements => New_List (Make_Exit_Statement (Loc)),
+ Discrete_Choices => New_List (L_Lo)));
+ end if;
+
else
-- Initial value is smallest value in predicate.
- D :=
- Make_Object_Declaration (Loc,
- Defining_Identifier => Loop_Id,
- Object_Definition => New_Occurrence_Of (Ltype, Loc),
- Expression => Lo_Val (First (Stat)));
+ if Is_Itype (Ltype) then
+ D :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Loop_Id,
+ Object_Definition => New_Occurrence_Of (Ltype, Loc),
+ Expression => L_Lo);
+ else
+ D :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Loop_Id,
+ Object_Definition => New_Occurrence_Of (Ltype, Loc),
+ Expression => Lo_Val (First (Stat)));
+ end if;
P := First (Stat);
while Present (P) loop
@@ -4823,6 +4865,17 @@
Next (P);
end loop;
+
+ if Is_Itype (Ltype)
+ and then Is_OK_Static_Expression (L_Hi)
+ and then
+ Expr_Value (L_Hi) /= Expr_Value (Lo_Val (Last (Stat)))
+ then
+ Append_To (Alts,
+ Make_Case_Statement_Alternative (Loc,
+ Statements => New_List (Make_Exit_Statement (Loc)),
+ Discrete_Choices => New_List (L_Hi)));
+ end if;
end if;
-- Add others choice
===================================================================
@@ -18449,6 +18449,19 @@
(Subt, Has_Static_Predicate_Aspect (Par));
Set_Has_Dynamic_Predicate_Aspect
(Subt, Has_Dynamic_Predicate_Aspect (Par));
+
+ -- A named subtype does not inherit the predicate function of its
+ -- parent but an itype declared for a loop index needs the discrete
+ -- predicate information of its parent to execute the loop properly.
+
+ if Is_Itype (Subt) and then Present (Predicate_Function (Par)) then
+ Set_Subprograms_For_Type (Subt, Subprograms_For_Type (Par));
+
+ if Has_Static_Predicate (Par) then
+ Set_Static_Discrete_Predicate
+ (Subt, Static_Discrete_Predicate (Par));
+ end if;
+ end if;
end Inherit_Predicate_Flags;
----------------------