aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEd Schonberg <schonberg@adacore.com>2021-01-07 20:12:34 -0500
committerPierre-Marie de Rodat <derodat@adacore.com>2021-05-05 04:18:58 -0400
commitd4780139532eefbccd8a52baf5206a0b08e851e9 (patch)
treebc51778b21fd74573e51a6d47eae559181c056b8 /gcc
parentec80b416554d3f41b5fd23cc86287af9b9a7d2d2 (diff)
downloadgcc-d4780139532eefbccd8a52baf5206a0b08e851e9.zip
gcc-d4780139532eefbccd8a52baf5206a0b08e851e9.tar.gz
gcc-d4780139532eefbccd8a52baf5206a0b08e851e9.tar.bz2
[Ada] Ongoing work for AI12-0212: container aggregates
gcc/ada/ * sem_aggr.adb (Resolve_Indexed_Aggregate): For indexed aggregates with component associations verify that if there is more than one component association then all the choices are static, that the set of choices define a continuous sequence of values, and that if loop specfications appear, they do not include iterator filters or key expressions.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/sem_aggr.adb107
1 files changed, 104 insertions, 3 deletions
diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb
index 0a2ce6b..ef95667 100644
--- a/gcc/ada/sem_aggr.adb
+++ b/gcc/ada/sem_aggr.adb
@@ -2980,9 +2980,12 @@ package body Sem_Aggr is
Index_Type : constant Entity_Id := Etype (Next_Formal (Container));
Comp_Type : constant Entity_Id :=
Etype (Next_Formal (Next_Formal (Container)));
- Comp : Node_Id;
- Choice : Node_Id;
+ Comp : Node_Id;
+ Choice : Node_Id;
+ Num_Choices : Nat := 0;
+ Hi_Val : Uint;
+ Lo_Val : Uint;
begin
if Present (Expressions (N)) then
Comp := First (Expressions (N));
@@ -2999,7 +3002,7 @@ package body Sem_Aggr is
return;
end if;
- Comp := First (Expressions (N));
+ Comp := First (Component_Associations (N));
while Present (Comp) loop
if Nkind (Comp) = N_Component_Association then
@@ -3007,6 +3010,7 @@ package body Sem_Aggr is
while Present (Choice) loop
Analyze_And_Resolve (Choice, Index_Type);
+ Num_Choices := Num_Choices + 1;
Next (Choice);
end loop;
@@ -3018,10 +3022,107 @@ package body Sem_Aggr is
then
Resolve_Iterated_Association
(Comp, Index_Type, Comp_Type);
+ Num_Choices := Num_Choices + 1;
end if;
Next (Comp);
end loop;
+
+ -- The component associations in an indexed aggregate
+ -- must denote a contiguous set of static values. We
+ -- build a table of values/ranges and sort it, as is done
+ -- elsewhere for case statements and array aggregates.
+ -- If the aggregate has a single iterated association it
+ -- is allowed to be nonstatic and there is nothing to check.
+
+ if Num_Choices > 1 then
+ declare
+ Table : Case_Table_Type (1 .. Num_Choices);
+ No_Choice : Pos := 1;
+ Lo, Hi : Node_Id;
+
+ -- Traverse aggregate to determine size of needed table.
+ -- Verify that bounds are static and that loops have no
+ -- filters or key expressions.
+
+ begin
+ Comp := First (Component_Associations (N));
+ while Present (Comp) loop
+ if Nkind (Comp) = N_Iterated_Element_Association then
+ if Present
+ (Loop_Parameter_Specification (Comp))
+ then
+ if Present (Iterator_Filter
+ (Loop_Parameter_Specification (Comp)))
+ then
+ Error_Msg_N
+ ("iterator filter not allowed " &
+ "in indexed aggregate", Comp);
+ return;
+
+ elsif Present (Key_Expression
+ (Loop_Parameter_Specification (Comp)))
+ then
+ Error_Msg_N
+ ("key expression not allowed " &
+ "in indexed aggregate", Comp);
+ return;
+ end if;
+ end if;
+ else
+ Choice := First (Choices (Comp));
+
+ while Present (Choice) loop
+ Get_Index_Bounds (Choice, Lo, Hi);
+ Table (No_Choice).Choice := Choice;
+ Table (No_Choice).Lo := Lo;
+ Table (No_Choice).Hi := Hi;
+
+ -- Verify staticness of value or range
+
+ if not Is_Static_Expression (Lo)
+ or else not Is_Static_Expression (Hi)
+ then
+ Error_Msg_N
+ ("nonstatic expression for index " &
+ "for indexed aggregate", Choice);
+ return;
+ end if;
+
+ No_Choice := No_Choice + 1;
+ Next (Choice);
+ end loop;
+ end if;
+
+ Next (Comp);
+ end loop;
+
+ Sort_Case_Table (Table);
+
+ for J in 1 .. Num_Choices - 1 loop
+ Hi_Val := Expr_Value (Table (J).Hi);
+ Lo_Val := Expr_Value (Table (J + 1).Lo);
+
+ if Lo_Val = Hi_Val then
+ Error_Msg_N
+ ("duplicate index in indexed aggregate",
+ Table (J + 1).Choice);
+ exit;
+
+ elsif Lo_Val < Hi_Val then
+ Error_Msg_N
+ ("overlapping indices in indexed aggregate",
+ Table (J + 1).Choice);
+ exit;
+
+ elsif Lo_Val > Hi_Val + 1 then
+ Error_Msg_N
+ ("missing index values", Table (J + 1).Choice);
+ exit;
+ end if;
+ end loop;
+ end;
+ end if;
end if;
end;
end if;