Commit fd5c81e9 by Eric Botcazou Committed by Eric Botcazou

decl.c (gnat_to_gnu_entity): Issue a warning on suspiciously large alignments specified for types.

	* decl.c (gnat_to_gnu_entity): Issue a warning on suspiciously
	large alignments specified for types.
	(validate_alignment): Minor cleanup.

From-SVN: r133012
parent 7f42aa36
2008-03-07 Eric Botcazou <ebotcazou@adacore.com>
* decl.c (gnat_to_gnu_entity): Issue a warning on suspiciously
large alignments specified for types.
(validate_alignment): Minor cleanup.
2008-03-07 Eric Botcazou <ebotcazou@adacore.com>
* decl.c (MAX_FIXED_MODE_SIZE): Define if not already defined.
(gnat_to_gnu_entity) <E_Record_Type>: Try to get a smaller form of
the component for packing, if possible, as well as if a component
......@@ -4086,8 +4086,38 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
if (align != 0 || TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE)
;
else if (Known_Alignment (gnat_entity))
{
align = validate_alignment (Alignment (gnat_entity), gnat_entity,
TYPE_ALIGN (gnu_type));
/* Warn on suspiciously large alignments. This should catch
errors about the (alignment,byte)/(size,bit) discrepancy. */
if (align > BIGGEST_ALIGNMENT && Has_Alignment_Clause (gnat_entity))
{
tree size;
/* If a size was specified, take it into account. Otherwise
use the RM size for records as the type size has already
been adjusted to the alignment. */
if (gnu_size)
size = gnu_size;
else if ((TREE_CODE (gnu_type) == RECORD_TYPE
|| TREE_CODE (gnu_type) == UNION_TYPE
|| TREE_CODE (gnu_type) == QUAL_UNION_TYPE)
&& !TYPE_IS_FAT_POINTER_P (gnu_type))
size = rm_size (gnu_type);
else
size = TYPE_SIZE (gnu_type);
/* Consider an alignment as suspicious if the alignment/size
ratio is greater or equal to the byte/bit ratio. */
if (host_integerp (size, 1)
&& align >= TREE_INT_CST_LOW (size) * BITS_PER_UNIT)
post_error_ne ("?suspiciously large alignment specified for&",
Expression (Alignment_Clause (gnat_entity)),
gnat_entity);
}
}
else if (Is_Atomic (gnat_entity) && !gnu_size
&& host_integerp (TYPE_SIZE (gnu_type), 1)
&& integer_pow2p (TYPE_SIZE (gnu_type)))
......@@ -6904,25 +6934,25 @@ make_type_from_size (tree type, tree size_tree, bool biased_p)
static unsigned int
validate_alignment (Uint alignment, Entity_Id gnat_entity, unsigned int align)
{
Node_Id gnat_error_node = gnat_entity;
unsigned int new_align;
unsigned int max_allowed_alignment = get_target_maximum_allowed_alignment ();
if (Present (Alignment_Clause (gnat_entity)))
gnat_error_node = Expression (Alignment_Clause (gnat_entity));
unsigned int new_align;
Node_Id gnat_error_node;
/* Don't worry about checking alignment if alignment was not specified
by the source program and we already posted an error for this entity. */
if (Error_Posted (gnat_entity) && !Has_Alignment_Clause (gnat_entity))
return align;
/* Post the error on the alignment clause if any. */
if (Present (Alignment_Clause (gnat_entity)))
gnat_error_node = Expression (Alignment_Clause (gnat_entity));
else
gnat_error_node = gnat_entity;
/* Within GCC, an alignment is an integer, so we must make sure a value is
specified that fits in that range. Also, there is an upper bound to
alignments we can support/allow. */
if (! UI_Is_In_Int_Range (alignment)
if (!UI_Is_In_Int_Range (alignment)
|| ((new_align = UI_To_Int (alignment)) > max_allowed_alignment))
post_error_ne_num ("largest supported alignment for& is ^",
gnat_error_node, gnat_entity, max_allowed_alignment);
......@@ -6933,7 +6963,11 @@ validate_alignment (Uint alignment, Entity_Id gnat_entity, unsigned int align)
gnat_error_node, gnat_entity,
align / BITS_PER_UNIT);
else
align = MAX (align, new_align == 0 ? 1 : new_align * BITS_PER_UNIT);
{
new_align = (new_align > 0 ? new_align * BITS_PER_UNIT : 1);
if (new_align > align)
align = new_align;
}
return align;
}
......
2008-03-07 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/specs/alignment2.ads: New test.
2008-03-07 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/pack3.adb: New test.
2008-03-07 Peter O'Gorman <pogma@thewrittenword.com>
with Interfaces; use Interfaces;
package Alignment2 is
-- warning
type R1 is record
A, B, C, D : Integer_8;
end record;
for R1'Size use 32;
for R1'Alignment use 32; -- { dg-warning "suspiciously large alignment" }
-- warning
type R2 is record
A, B, C, D : Integer_8;
end record;
for R2'Alignment use 32; -- { dg-warning "suspiciously large alignment" }
-- OK, big size
type R3 is record
A, B, C, D : Integer_8;
end record;
for R3'Size use 32 * 8;
for R3'Alignment use 32;
-- OK, big size
type R4 is record
A, B, C, D, E, F, G, H : Integer_32;
end record;
for R4'Alignment use 32;
-- warning
type I1 is new Integer_32;
for I1'Size use 32;
for I1'Alignment use 32; -- { dg-warning "suspiciously large alignment" }
-- warning
type I2 is new Integer_32;
for I2'Alignment use 32; -- { dg-warning "suspiciously large alignment" }
-- OK, big size
type I3 is new Integer_32;
for I3'Size use 32 * 8;
for I3'Alignment use 32;
end Alignment2;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment