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> 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. * 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 (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 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) ...@@ -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) if (align != 0 || TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE)
; ;
else if (Known_Alignment (gnat_entity)) else if (Known_Alignment (gnat_entity))
align = validate_alignment (Alignment (gnat_entity), gnat_entity, {
TYPE_ALIGN (gnu_type)); 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 else if (Is_Atomic (gnat_entity) && !gnu_size
&& host_integerp (TYPE_SIZE (gnu_type), 1) && host_integerp (TYPE_SIZE (gnu_type), 1)
&& integer_pow2p (TYPE_SIZE (gnu_type))) && integer_pow2p (TYPE_SIZE (gnu_type)))
...@@ -6904,25 +6934,25 @@ make_type_from_size (tree type, tree size_tree, bool biased_p) ...@@ -6904,25 +6934,25 @@ make_type_from_size (tree type, tree size_tree, bool biased_p)
static unsigned int static unsigned int
validate_alignment (Uint alignment, Entity_Id gnat_entity, unsigned int align) 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 (); unsigned int max_allowed_alignment = get_target_maximum_allowed_alignment ();
unsigned int new_align;
if (Present (Alignment_Clause (gnat_entity))) Node_Id gnat_error_node;
gnat_error_node = Expression (Alignment_Clause (gnat_entity));
/* Don't worry about checking alignment if alignment was not specified /* Don't worry about checking alignment if alignment was not specified
by the source program and we already posted an error for this entity. */ by the source program and we already posted an error for this entity. */
if (Error_Posted (gnat_entity) && !Has_Alignment_Clause (gnat_entity)) if (Error_Posted (gnat_entity) && !Has_Alignment_Clause (gnat_entity))
return align; 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 /* 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 specified that fits in that range. Also, there is an upper bound to
alignments we can support/allow. */ 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)) || ((new_align = UI_To_Int (alignment)) > max_allowed_alignment))
post_error_ne_num ("largest supported alignment for& is ^", post_error_ne_num ("largest supported alignment for& is ^",
gnat_error_node, gnat_entity, max_allowed_alignment); gnat_error_node, gnat_entity, max_allowed_alignment);
...@@ -6933,7 +6963,11 @@ validate_alignment (Uint alignment, Entity_Id gnat_entity, unsigned int align) ...@@ -6933,7 +6963,11 @@ validate_alignment (Uint alignment, Entity_Id gnat_entity, unsigned int align)
gnat_error_node, gnat_entity, gnat_error_node, gnat_entity,
align / BITS_PER_UNIT); align / BITS_PER_UNIT);
else 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; return align;
} }
......
2008-03-07 Eric Botcazou <ebotcazou@adacore.com> 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. * gnat.dg/pack3.adb: New test.
2008-03-07 Peter O'Gorman <pogma@thewrittenword.com> 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