[Ada] Extend -gnatw.z warning to array types

The -gnatw.z switch causes the compiler to issue a warning on record
types subject to both an alignment clause and a size clause, when the
specified size is not a multiple of the alignment in bits, because this
means that the Object_Size will be strictly larger than the specified
size.

It makes sense to extend this warning to array types, but not to the
cases of bit-packed arrays where the size is not a multiple of storage
unit and the specified alignment is the minimum one, because there would
be no way to get rid of it apart from explicitly silencing it.

The compiler must issue the warning:

p.ads:5:03: warning: size is not a multiple of alignment for "Triplet"
p.ads:5:03: warning: size of 24 specified at line 4
p.ads:5:03: warning: Object_Size will be increased to 32

on the following package:

package P is

  type Triplet is new String (1 .. 3);
  for Triplet'Size use 24;
  for Triplet'Alignment use 4;

  type Arr is array (1 .. 7) of Boolean;
  pragma Pack (Arr);
  for Arr'Size use 7;
  for Arr'Alignment use 1;

end P;

2019-07-03  Eric Botcazou  <ebotcazou@adacore.com>

gcc/ada/

	* doc/gnat_ugn/building_executable_programs_with_gnat.rst
	(Warning message control): Document that -gnatw.z/Z apply to
	array types.
	* freeze.adb (Freeze_Entity): Give -gnatw.z warning for array
	types as well, but not if the specified alignment is the minimum
	one.
	* gnat_ugn.texi: Regenerate.

From-SVN: r272971
This commit is contained in:
Eric Botcazou 2019-07-03 08:14:33 +00:00 committed by Pierre-Marie de Rodat
parent 1f159b86c1
commit bf4f18bded
4 changed files with 38 additions and 23 deletions

View File

@ -1,3 +1,13 @@
2019-07-03 Eric Botcazou <ebotcazou@adacore.com>
* doc/gnat_ugn/building_executable_programs_with_gnat.rst
(Warning message control): Document that -gnatw.z/Z apply to
array types.
* freeze.adb (Freeze_Entity): Give -gnatw.z warning for array
types as well, but not if the specified alignment is the minimum
one.
* gnat_ugn.texi: Regenerate.
2019-07-03 Bob Duff <duff@adacore.com>
* einfo.ads, exp_util.adb, layout.ads, sinfo.ads: Spell "laid"

View File

@ -4045,8 +4045,8 @@ of the pragma in the :title:`GNAT_Reference_manual`).
:switch:`-gnatw.z`
*Activate warnings for size not a multiple of alignment.*
This switch activates warnings for cases of record types with
specified ``Size`` and ``Alignment`` attributes where the
This switch activates warnings for cases of array and record types
with specified ``Size`` and ``Alignment`` attributes where the
size is not a multiple of the alignment, resulting in an object
size that is greater than the specified size. The default
is that such warnings are generated.
@ -4058,12 +4058,11 @@ of the pragma in the :title:`GNAT_Reference_manual`).
:switch:`-gnatw.Z`
*Suppress warnings for size not a multiple of alignment.*
This switch suppresses warnings for cases of record types with
specified ``Size`` and ``Alignment`` attributes where the
This switch suppresses warnings for cases of array and record types
with specified ``Size`` and ``Alignment`` attributes where the
size is not a multiple of the alignment, resulting in an object
size that is greater than the specified size.
The warning can also be
suppressed by giving an explicit ``Object_Size`` value.
size that is greater than the specified size. The warning can also
be suppressed by giving an explicit ``Object_Size`` value.
.. index:: -Wunused (gcc)

View File

@ -5943,17 +5943,29 @@ package body Freeze is
Inherit_Aspects_At_Freeze_Point (E);
end if;
-- Check for incompatible size and alignment for record type
-- Case of array type
if Is_Array_Type (E) then
Freeze_Array_Type (E);
end if;
-- Check for incompatible size and alignment for array/record type
if Warn_On_Size_Alignment
and then Is_Record_Type (E)
and then Has_Size_Clause (E) and then Has_Alignment_Clause (E)
and then (Is_Array_Type (E) or else Is_Record_Type (E))
and then Has_Size_Clause (E)
and then Has_Alignment_Clause (E)
-- If explicit Object_Size clause given assume that the programmer
-- knows what he is doing, and expects the compiler behavior.
and then not Has_Object_Size_Clause (E)
-- It does not really make sense to warn for the minimum alignment
-- since the programmer could not get rid of the warning.
and then Alignment (E) > 1
-- Check for size not a multiple of alignment
and then RM_Size (E) mod (Alignment (E) * System_Storage_Unit) /= 0
@ -5994,15 +6006,10 @@ package body Freeze is
end;
end if;
-- Array type
if Is_Array_Type (E) then
Freeze_Array_Type (E);
-- For a class-wide type, the corresponding specific type is
-- frozen as well (RM 13.14(15))
elsif Is_Class_Wide_Type (E) then
if Is_Class_Wide_Type (E) then
Freeze_And_Append (Root_Type (E), N, Result);
-- If the base type of the class-wide type is still incomplete,

View File

@ -12683,8 +12683,8 @@ sizes or conventions.
@emph{Activate warnings for size not a multiple of alignment.}
This switch activates warnings for cases of record types with
specified @code{Size} and @code{Alignment} attributes where the
This switch activates warnings for cases of array and record types
with specified @code{Size} and @code{Alignment} attributes where the
size is not a multiple of the alignment, resulting in an object
size that is greater than the specified size. The default
is that such warnings are generated.
@ -12701,12 +12701,11 @@ is that such warnings are generated.
@emph{Suppress warnings for size not a multiple of alignment.}
This switch suppresses warnings for cases of record types with
specified @code{Size} and @code{Alignment} attributes where the
This switch suppresses warnings for cases of array and record types
with specified @code{Size} and @code{Alignment} attributes where the
size is not a multiple of the alignment, resulting in an object
size that is greater than the specified size.
The warning can also be
suppressed by giving an explicit @code{Object_Size} value.
size that is greater than the specified size. The warning can also
be suppressed by giving an explicit @code{Object_Size} value.
@end table
@geindex -Wunused (gcc)