This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] Give warnings on questionable layout of record types


This implements a warning on the questionable placement of specific sorts
of components in record types, more specifically those with non-fixed size
or those with a fixed size that is not a mutiple of the storage unit.  It
is enabled by -gnatw.q (and disabled by -gnatw.Q) only for the time being.

The placement of these fields can be problematic if they are followed in
textual order by regular fields and there is no representation clause for
them, because accesses to the latter fields may be most costly, both in
terms of code size and performance at run time.

Here's an example on a package compiled with -gnatw.q -gnatl:

     1. with Q; use Q;
     2.
     3. package P is
     4.
     5.   --  All fixed length => No reordering
     6.   type R1 is record
     7.     S1 : Short_Integer;
     8.     I1 : Integer;
     9.     S2 : Short_Integer;
    10.   end record;
    11.
    12.   -- A1 variable length => Moved to the end
    13.   type R2 is record
    14.     A1 : Arr (1 .. Q.N);
            |
        >>> warning: record layout may cause performance issues
        >>> warning: component "A1" whose length is not fixed
        >>> warning: comes too early and ought to be moved down

    15.     I1 : Integer;
    16.     S1 : Short_Integer;
    17.   end record;
    18.
    19.   -- A1 self-referential length => Moved to the end
    20.   type R3 (D : My_Index) is record
    21.     A1 : Arr (1 .. D);
            |
        >>> warning: record layout may cause performance issues
        >>> warning: component "A1" whose length depends on a discriminant
        >>> warning: comes too early and ought to be moved down

    22.     I1 : Integer;
    23.     S1 : Short_Integer;
    24.   end record;
    25.
    26.   -- A1 self-referential length => Moved to the end
    27.   -- A2 variable length => Moved to right before A1
    28.   type R4 (D : My_Index) is record
    29.     A1 : Arr (1 .. D);
            |
        >>> warning: record layout may cause performance issues
        >>> warning: component "A1" whose length depends on a discriminant
        >>> warning: comes too early and ought to be moved down

    30.     A2 : Arr (1 .. Q.N);
            |
        >>> warning: record layout may cause performance issues
        >>> warning: component "A2" whose length is not fixed
        >>> warning: comes too early and ought to be moved down

    31.     I1 : Integer;
    32.     S1 : Short_Integer;
    33.   end record;
    34.
    35.   -- A1 variable length => Moved to right before the variant part
    36.   type R5 (D : My_Index) is record
    37.     A1 : Arr (1 .. Q.N);
            |
        >>> warning: record layout may cause performance issues
        >>> warning: component "A1" whose length is not fixed
        >>> warning: comes too early and ought to be moved down

    38.     I1 : Integer;
    39.     S1 : Short_Integer;
    40.     case D is
    41.       when 1 =>
    42.         I2 : Integer;
    43.       when others =>
    44.         S2 : Short_Integer;
    45.     end case;
    46.   end record;
    47.
    48.   -- A1 variable length => Moved to the end of the variant
    49.   -- A2 self-referential length => Moved to the end of the variant
    50.   type R6 (D : My_Index) is record
    51.     S1 : Short_Integer;
    52.     case D is
    53.       when 1 =>
    54.         A1 : Arr (1 .. Q.N);
                |
        >>> warning: variant layout may cause performance issues
        >>> warning: component "A1" whose length is not fixed
        >>> warning: comes too early and ought to be moved down

    55.         I1 : Integer;
    56.       when others =>
    57.         A2 : Arr (1 .. D);
                |
        >>> warning: variant layout may cause performance issues
        >>> warning: component "A2" whose length depends on a discriminant
        >>> warning: comes too early and ought to be moved down

    58.         S2 : Short_Integer;
    59.     end case;
    60.   end record;
    61.
    62. end P;

 62 lines: No errors, 21 warnings

Tested on x86_64-pc-linux-gnu, committed on trunk

2017-04-27  Eric Botcazou  <ebotcazou@adacore.com>

	* fe.h (Warn_On_Questionable_Layout): Declare.
	* warnsw.ads (Warn_On_Record_Holes): Move down.
	(Warn_On_Questionable_Layout): New boolean variable.
	(Warning_Record): Add Warn_On_Questionable_Layout field.
	* warnsw.adb (All_Warnings): Set Warn_On_Questionable_Layout.
	(Restore_Warnings): Likewise.
	(Save_Warnings): Likewise.
	(Set_Dot_Warning_Switch): Handle 'q' and 'Q' letters.
	* gcc-interface/decl.c (gnat_to_gnu_entity): Adjust call to
	components_to_record.
	(gnu_field_to_gnat): New function.
	(warn_on_field_placement): Likewise.
	(components_to_record): Add GNAT_RECORD_TYPE and remove REORDER
	parameters.  Rename local variables and adjust recursive call.
	Rework final scan of the field list and implement warnings on the
	problematic placement of specific sorts of fields.

Attachment: difs
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]