From: Eric Botcazou <[email protected]>
This has been exposed by the latest change made to Resolve_Allocator: the
constraints of a subtype indication are not necessarily given in the same
order as the discriminants of the base type in the source code.
gcc/ada/ChangeLog:
* sem_res.adb (Check_Discriminant_Use): Rename PN local variable as
Par and apply minor formatting tweaks.
(Resolve_Allocator): For the subtype indication form, make sure to
take the constraints of a subtype into account instead of those of
the indication in order to implement the static accessibility check.
Tested on x86_64-pc-linux-gnu, committed on master.
---
gcc/ada/sem_res.adb | 90 +++++++++++++++++++++++++--------------------
1 file changed, 51 insertions(+), 39 deletions(-)
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index c91ae4e476b..f2eeaf8fbfd 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -646,10 +646,8 @@ package body Sem_Res is
----------------------------
procedure Check_Discriminant_Use (N : Node_Id) is
- PN : constant Node_Id := Parent (N);
+ Par : constant Node_Id := Parent (N);
Disc : constant Entity_Id := Entity (N);
- P : Node_Id;
- D : Node_Id;
procedure Check_Legality_In_Constraint (Alone : Boolean);
-- RM 3.8(12/3): Check that the discriminant mentioned in a constraint
@@ -669,17 +667,24 @@ package body Sem_Res is
end if;
end Check_Legality_In_Constraint;
+ -- Local variables
+
+ P : Node_Id;
+ D : Node_Id;
+
+ -- Start of processing for Check_Discriminant_Use
+
begin
-- Any use in a spec-expression is legal
if In_Spec_Expression then
null;
- elsif Nkind (PN) = N_Range then
+ elsif Nkind (Par) = N_Range then
-- Discriminant cannot be used to constrain a scalar type
- P := Parent (PN);
+ P := Parent (Par);
if Nkind (P) = N_Range_Constraint
and then Nkind (Parent (P)) = N_Subtype_Indication
@@ -761,7 +766,7 @@ package body Sem_Res is
-- Check that it is the high bound
- if N /= High_Bound (PN)
+ if N /= High_Bound (Par)
or else No (Discriminant_Default_Value (Disc))
then
goto No_Danger;
@@ -789,13 +794,13 @@ package body Sem_Res is
while True
and then Present (TB)
and then Present (CB)
- and then CB /= PN
+ and then CB /= Par
loop
Next_Index (TB);
Next (CB);
end loop;
- if CB /= PN then
+ if CB /= Par then
goto No_Danger;
end if;
@@ -817,8 +822,8 @@ package body Sem_Res is
-- Legal case is in index or discriminant constraint
- elsif Nkind (PN) in N_Index_Or_Discriminant_Constraint
- | N_Discriminant_Association
+ elsif Nkind (Par) in N_Index_Or_Discriminant_Constraint
+ | N_Discriminant_Association
then
Check_Legality_In_Constraint (Paren_Count (N) = 0);
@@ -826,8 +831,8 @@ package body Sem_Res is
-- subexpression of) a constraint for a component.
else
- D := PN;
- P := Parent (PN);
+ D := Par;
+ P := Parent (Par);
while Nkind (P) not in
N_Component_Declaration | N_Subtype_Indication | N_Entry_Declaration
loop
@@ -5328,14 +5333,8 @@ package body Sem_Res is
-----------------------
procedure Resolve_Allocator (N : Node_Id; Typ : Entity_Id) is
- Desig_T : constant Entity_Id := Designated_Type (Typ);
- E : constant Node_Id := Expression (N);
- Subtyp : Entity_Id;
- Discrim : Entity_Id;
- Constr : Node_Id;
- Exp : Node_Id;
- Assoc : Node_Id := Empty;
- Disc_Exp : Node_Id;
+ Desig_T : constant Entity_Id := Designated_Type (Typ);
+ E : constant Node_Id := Expression (N);
procedure Accessibility_Error (Exp : Node_Id);
-- Give an error about the accessibility level of the allocator
@@ -5486,6 +5485,15 @@ package body Sem_Res is
and then Is_Dispatching_Operation (Entity (Name (Par)));
end In_Dispatching_Context;
+ -- Local variables
+
+ Assoc : Node_Id;
+ Disc_Exp : Node_Id;
+ Disc_Elmt : Elmt_Id;
+ Discrim : Entity_Id;
+ Exp : Node_Id;
+ Subtyp : Entity_Id;
+
-- Start of processing for Resolve_Allocator
begin
@@ -5593,6 +5601,8 @@ package body Sem_Res is
-- Get the first component expression of the aggregate
+ Assoc := Empty;
+
if Present (Expressions (Exp)) then
Disc_Exp := First (Expressions (Exp));
@@ -5670,30 +5680,32 @@ package body Sem_Res is
-- of the access discriminant.
if Nkind (Original_Node (E)) = N_Subtype_Indication
+ and then Has_Anonymous_Access_Discriminant
+ (Entity (Subtype_Mark (Original_Node (E))))
and then (Ekind (Typ) /= E_Anonymous_Access_Type
or else Is_Local_Anonymous_Access (Typ))
then
- Subtyp := Entity (Subtype_Mark (Original_Node (E)));
+ -- We cannot directly use the constraints of a subtype indication
+ -- because they are not necessarily given in the expected order.
- if Has_Anonymous_Access_Discriminant (Subtyp) then
- Discrim := First_Discriminant (Base_Type (Subtyp));
- Constr := First (Constraints (Constraint (Original_Node (E))));
- while Present (Discrim) and then Present (Constr) loop
- if Ekind (Etype (Discrim)) = E_Anonymous_Access_Type then
- if Nkind (Constr) = N_Discriminant_Association then
- Disc_Exp := Expression (Constr);
- else
- Disc_Exp := Constr;
- end if;
-
- Check_Allocator_Discrim_Accessibility_Exprs
- (Disc_Exp, Typ);
- end if;
-
- Next_Discriminant (Discrim);
- Next (Constr);
- end loop;
+ if Nkind (E) = N_Subtype_Indication then
+ Subtyp := Process_Subtype (E, N);
+ else
+ Subtyp := Etype (E);
end if;
+
+ Discrim := First_Discriminant (Base_Type (Subtyp));
+ Disc_Elmt := First_Elmt (Discriminant_Constraint (Subtyp));
+
+ while Present (Discrim) loop
+ if Ekind (Etype (Discrim)) = E_Anonymous_Access_Type then
+ Disc_Exp := Node (Disc_Elmt);
+ Check_Allocator_Discrim_Accessibility_Exprs (Disc_Exp, Typ);
+ end if;
+
+ Next_Discriminant (Discrim);
+ Next_Elmt (Disc_Elmt);
+ end loop;
end if;
end if;
--
2.53.0