aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sem_ch13.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sem_ch13.adb')
-rw-r--r--gcc/ada/sem_ch13.adb79
1 files changed, 70 insertions, 9 deletions
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index dec542b..4156879 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -10133,6 +10133,11 @@ package body Sem_Ch13 is
-- recursively to compute After_Last for the parent type; in this case
-- Warn is False and the warnings are suppressed.
+ procedure Component_Order_Check (Rectype : Entity_Id);
+ -- Check that the order of component clauses agrees with the order of
+ -- component declarations, and that the component clauses are given in
+ -- increasing order of bit offset.
+
-----------------------------
-- Check_Component_Overlap --
-----------------------------
@@ -10175,6 +10180,53 @@ package body Sem_Ch13 is
end if;
end Check_Component_Overlap;
+ ---------------------------
+ -- Component_Order_Check --
+ ---------------------------
+
+ procedure Component_Order_Check (Rectype : Entity_Id) is
+ Comp : Entity_Id := First_Component (Rectype);
+ Clause : Node_Id := First (Component_Clauses (N));
+ Prev_Bit_Offset : Uint := Uint_0;
+ OOO : constant String :=
+ "?component clause out of order with respect to declaration";
+
+ begin
+ -- Step Comp through components and Clause through component clauses,
+ -- skipping pragmas. We ignore discriminants and variant parts,
+ -- because we get most of the benefit from the plain vanilla
+ -- component cases, without the extra complexity. If we find a Comp
+ -- and Clause that don't match, give a warning on both and quit. If
+ -- we find two subsequent clauses out of order by bit layout, give
+ -- warning and quit. On each iteration, Prev_Bit_Offset is the one
+ -- from the previous iteration (or 0 to start).
+
+ while Present (Comp) and then Present (Clause) loop
+ if Nkind (Clause) = N_Component_Clause
+ and then Ekind (Entity (Component_Name (Clause))) = E_Component
+ then
+ if Entity (Component_Name (Clause)) /= Comp then
+ Error_Msg_N (OOO, Comp);
+ Error_Msg_N (OOO, Clause);
+ exit;
+ end if;
+
+ if not Reverse_Bit_Order (Rectype)
+ and then not Reverse_Storage_Order (Rectype)
+ and then Component_Bit_Offset (Comp) < Prev_Bit_Offset
+ then
+ Error_Msg_N ("?memory layout out of order", Clause);
+ exit;
+ end if;
+
+ Prev_Bit_Offset := Component_Bit_Offset (Comp);
+ Comp := Next_Component (Comp);
+ end if;
+
+ Next (Clause);
+ end loop;
+ end Component_Order_Check;
+
--------------------
-- Find_Component --
--------------------
@@ -10821,16 +10873,25 @@ package body Sem_Ch13 is
end Overlap_Check2;
end if;
- -- Check for record holes (gaps). We skip this check if overlap was
- -- detected, since it makes sense for the programmer to fix this
- -- error before worrying about warnings.
+ -- Skip the following warnings if overlap was detected; programmer
+ -- should fix the errors first.
- if Warn_On_Record_Holes and not Overlap_Detected then
- declare
- Ignore : Uint;
- begin
- Record_Hole_Check (Rectype, After_Last => Ignore, Warn => True);
- end;
+ if not Overlap_Detected then
+ -- Check for record holes (gaps)
+
+ if Warn_On_Record_Holes then
+ declare
+ Ignore : Uint;
+ begin
+ Record_Hole_Check (Rectype, After_Last => Ignore, Warn => True);
+ end;
+ end if;
+
+ -- Check for out-of-order component clauses
+
+ if Warn_On_Component_Order then
+ Component_Order_Check (Rectype);
+ end if;
end if;
-- For records that have component clauses for all components, and whose