[Ada] Warning for out-of-order record representation clauses
The compiler can now warn for out-of-order record representation clauses. A warning is given if the order of component declarations, component clauses, and bit-level layout do not all agree. The warning is disabled by default, and may be enabled by the -gnatw_r switch. 2019-08-20 Bob Duff <duff@adacore.com> gcc/ada/ * sem_ch13.adb (Component_Order_Check): New procedure to check for out-of-order clauses. * warnsw.ads, warnsw.adb: New -gnatw_r switch. * doc/gnat_ugn/building_executable_programs_with_gnat.rst: Document new switch. * gnat_ugn.texi: Regenerate. From-SVN: r274723
This commit is contained in:
parent
afdc759841
commit
94f76dc10c
@ -1,3 +1,12 @@
|
||||
2019-08-20 Bob Duff <duff@adacore.com>
|
||||
|
||||
* sem_ch13.adb (Component_Order_Check): New procedure to check
|
||||
for out-of-order clauses.
|
||||
* warnsw.ads, warnsw.adb: New -gnatw_r switch.
|
||||
* doc/gnat_ugn/building_executable_programs_with_gnat.rst:
|
||||
Document new switch.
|
||||
* gnat_ugn.texi: Regenerate.
|
||||
|
||||
2019-08-20 Bob Duff <duff@adacore.com>
|
||||
|
||||
* sem_ch13.adb (Object_Size): Give an error for zero. It really
|
||||
|
@ -2760,7 +2760,7 @@ of the pragma in the :title:`GNAT_Reference_manual`).
|
||||
:switch:`-gnatwa`
|
||||
*Activate most optional warnings.*
|
||||
|
||||
This switch activates most optional warning messages. See the remaining list
|
||||
This switch activates most optional warning messages. See the remaining list
|
||||
in this section for details on optional warning messages that can be
|
||||
individually controlled. The warnings that are not turned on by this
|
||||
switch are:
|
||||
@ -2790,6 +2790,8 @@ of the pragma in the :title:`GNAT_Reference_manual`).
|
||||
|
||||
* :switch:`-gnatw.q` (questionable layout of record types)
|
||||
|
||||
* :switch:`-gnatw_r` (out-of-order record representation clauses)
|
||||
|
||||
* :switch:`-gnatw.s` (overridden size clause)
|
||||
|
||||
* :switch:`-gnatwt` (tracking of deleted conditional code)
|
||||
@ -3708,7 +3710,7 @@ of the pragma in the :title:`GNAT_Reference_manual`).
|
||||
warnings are given.
|
||||
|
||||
|
||||
.. index:: -gnatwT (gcc)
|
||||
.. index:: -gnatw.R (gcc)
|
||||
|
||||
:switch:`-gnatw.R`
|
||||
*Suppress warnings for object renaming function.*
|
||||
@ -3716,6 +3718,23 @@ of the pragma in the :title:`GNAT_Reference_manual`).
|
||||
This switch suppresses warnings for object renaming function.
|
||||
|
||||
|
||||
.. index:: -gnatw_r (gcc)
|
||||
|
||||
:switch:`-gnatw_r`
|
||||
*Activate warnings for out-of-order record representation clauses.*
|
||||
|
||||
This switch activates warnings for record representation clauses,
|
||||
if the order of component declarations, component clauses,
|
||||
and bit-level layout do not all agree.
|
||||
The default is that these warnings are not given.
|
||||
|
||||
|
||||
.. index:: -gnatw_R (gcc)
|
||||
|
||||
:switch:`-gnatw_R`
|
||||
*Suppress warnings for out-of-order record representation clauses.*
|
||||
|
||||
|
||||
.. index:: -gnatws (gcc)
|
||||
|
||||
:switch:`-gnatws`
|
||||
|
@ -10925,7 +10925,7 @@ of the pragma in the @cite{GNAT_Reference_manual}).
|
||||
|
||||
@emph{Activate most optional warnings.}
|
||||
|
||||
This switch activates most optional warning messages. See the remaining list
|
||||
This switch activates most optional warning messages. See the remaining list
|
||||
in this section for details on optional warning messages that can be
|
||||
individually controlled. The warnings that are not turned on by this
|
||||
switch are:
|
||||
@ -10969,6 +10969,9 @@ switch are:
|
||||
@item
|
||||
@code{-gnatw.q} (questionable layout of record types)
|
||||
|
||||
@item
|
||||
@code{-gnatw_r} (out-of-order record representation clauses)
|
||||
|
||||
@item
|
||||
@code{-gnatw.s} (overridden size clause)
|
||||
|
||||
@ -12225,7 +12228,7 @@ opposed to renaming the function itself). The default is that these
|
||||
warnings are given.
|
||||
@end table
|
||||
|
||||
@geindex -gnatwT (gcc)
|
||||
@geindex -gnatw.R (gcc)
|
||||
|
||||
|
||||
@table @asis
|
||||
@ -12237,6 +12240,31 @@ warnings are given.
|
||||
This switch suppresses warnings for object renaming function.
|
||||
@end table
|
||||
|
||||
@geindex -gnatw_r (gcc)
|
||||
|
||||
|
||||
@table @asis
|
||||
|
||||
@item @code{-gnatw_r}
|
||||
|
||||
@emph{Activate warnings for out-of-order record representation clauses.}
|
||||
|
||||
This switch activates warnings for record representation clauses,
|
||||
if the order of component declarations, component clauses,
|
||||
and bit-level layout do not all agree.
|
||||
The default is that these warnings are not given.
|
||||
@end table
|
||||
|
||||
@geindex -gnatw_R (gcc)
|
||||
|
||||
|
||||
@table @asis
|
||||
|
||||
@item @code{-gnatw_R}
|
||||
|
||||
@emph{Suppress warnings for out-of-order record representation clauses.}
|
||||
@end table
|
||||
|
||||
@geindex -gnatws (gcc)
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -79,6 +79,7 @@ package body Warnsw is
|
||||
Warn_On_Questionable_Layout := Setting;
|
||||
Warn_On_Questionable_Missing_Parens := Setting;
|
||||
Warn_On_Record_Holes := Setting;
|
||||
Warn_On_Component_Order := Setting;
|
||||
Warn_On_Redundant_Constructs := Setting;
|
||||
Warn_On_Reverse_Bit_Order := Setting;
|
||||
Warn_On_Size_Alignment := Setting;
|
||||
@ -177,6 +178,8 @@ package body Warnsw is
|
||||
W.Warn_On_Questionable_Missing_Parens;
|
||||
Warn_On_Record_Holes :=
|
||||
W.Warn_On_Record_Holes;
|
||||
Warn_On_Component_Order :=
|
||||
W.Warn_On_Component_Order;
|
||||
Warn_On_Redundant_Constructs :=
|
||||
W.Warn_On_Redundant_Constructs;
|
||||
Warn_On_Reverse_Bit_Order :=
|
||||
@ -287,6 +290,8 @@ package body Warnsw is
|
||||
Warn_On_Questionable_Missing_Parens;
|
||||
W.Warn_On_Record_Holes :=
|
||||
Warn_On_Record_Holes;
|
||||
W.Warn_On_Component_Order :=
|
||||
Warn_On_Component_Order;
|
||||
W.Warn_On_Redundant_Constructs :=
|
||||
Warn_On_Redundant_Constructs;
|
||||
W.Warn_On_Reverse_Bit_Order :=
|
||||
@ -500,6 +505,12 @@ package body Warnsw is
|
||||
when 'C' =>
|
||||
Warn_On_Unknown_Compile_Time_Warning := False;
|
||||
|
||||
when 'r' =>
|
||||
Warn_On_Component_Order := True;
|
||||
|
||||
when 'R' =>
|
||||
Warn_On_Component_Order := False;
|
||||
|
||||
when others =>
|
||||
if Ignore_Unrecognized_VWY_Switches then
|
||||
Write_Line ("unrecognized switch -gnatw_" & C & " ignored");
|
||||
|
@ -67,6 +67,12 @@ package Warnsw is
|
||||
-- Warn when explicit record component clauses leave uncovered holes (gaps)
|
||||
-- in a record layout. Off by default, set by -gnatw.h (but not -gnatwa).
|
||||
|
||||
Warn_On_Component_Order : Boolean := False;
|
||||
-- Warn when record component clauses are out of order with respect to the
|
||||
-- component declarations, or if the memory layout is out of order with
|
||||
-- respect to component declarations and clauses. Off by default, set by
|
||||
-- -gnatw_r (but not -gnatwa).
|
||||
|
||||
Warn_On_Size_Alignment : Boolean := True;
|
||||
-- Warn when explicit Size and Alignment clauses are given for a type, and
|
||||
-- the size is not a multiple of the alignment. Off by default, modified
|
||||
@ -123,6 +129,7 @@ package Warnsw is
|
||||
Warn_On_Questionable_Layout : Boolean;
|
||||
Warn_On_Questionable_Missing_Parens : Boolean;
|
||||
Warn_On_Record_Holes : Boolean;
|
||||
Warn_On_Component_Order : Boolean;
|
||||
Warn_On_Redundant_Constructs : Boolean;
|
||||
Warn_On_Reverse_Bit_Order : Boolean;
|
||||
Warn_On_Size_Alignment : Boolean;
|
||||
|
Loading…
Reference in New Issue
Block a user