Fix bogus alignment warning on address clause
The compiler gives a bogus alignment warning on an address clause and a discriminated record type with variable size. gcc/ada/ChangeLog: * gcc-interface/decl.c (maybe_saturate_size): Add ALIGN parameter and round down the result to ALIGN. (gnat_to_gnu_entity): Adjust calls to maybe_saturate_size. gcc/testsuite/ChangeLog: * gnat.dg/addr16.adb: New test. * gnat.dg/addr16_pkg.ads: New helper.
This commit is contained in:
parent
dabef758bf
commit
88795e14ae
@ -232,7 +232,7 @@ static tree build_position_list (tree, bool, tree, tree, unsigned int, tree);
|
||||
static vec<subst_pair> build_subst_list (Entity_Id, Entity_Id, bool);
|
||||
static vec<variant_desc> build_variant_list (tree, Node_Id, vec<subst_pair>,
|
||||
vec<variant_desc>);
|
||||
static tree maybe_saturate_size (tree);
|
||||
static tree maybe_saturate_size (tree, unsigned int align);
|
||||
static tree validate_size (Uint, tree, Entity_Id, enum tree_code, bool, bool,
|
||||
const char *, const char *);
|
||||
static void set_rm_size (Uint, tree, Entity_Id);
|
||||
@ -4425,7 +4425,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
|
||||
/* If the size is self-referential, annotate the maximum value
|
||||
after saturating it, if need be, to avoid a No_Uint value. */
|
||||
if (CONTAINS_PLACEHOLDER_P (gnu_size))
|
||||
gnu_size = maybe_saturate_size (max_size (gnu_size, true));
|
||||
{
|
||||
const unsigned int align
|
||||
= UI_To_Int (Alignment (gnat_entity)) * BITS_PER_UNIT;
|
||||
gnu_size
|
||||
= maybe_saturate_size (max_size (gnu_size, true), align);
|
||||
}
|
||||
|
||||
/* If we are just annotating types and the type is tagged, the tag
|
||||
and the parent components are not generated by the front-end so
|
||||
@ -4461,7 +4466,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
|
||||
gnu_size = size_binop (PLUS_EXPR, gnu_size, offset);
|
||||
}
|
||||
|
||||
gnu_size = maybe_saturate_size (round_up (gnu_size, align));
|
||||
gnu_size
|
||||
= maybe_saturate_size (round_up (gnu_size, align), align);
|
||||
Set_Esize (gnat_entity, annotate_value (gnu_size));
|
||||
|
||||
/* Tagged types are Strict_Alignment so RM_Size = Esize. */
|
||||
@ -8946,15 +8952,21 @@ build_variant_list (tree gnu_qual_union_type, Node_Id gnat_variant_part,
|
||||
}
|
||||
|
||||
/* If SIZE has overflowed, return the maximum valid size, which is the upper
|
||||
bound of the signed sizetype in bits; otherwise return SIZE unmodified. */
|
||||
bound of the signed sizetype in bits, rounded down to ALIGN. Otherwise
|
||||
return SIZE unmodified. */
|
||||
|
||||
static tree
|
||||
maybe_saturate_size (tree size)
|
||||
maybe_saturate_size (tree size, unsigned int align)
|
||||
{
|
||||
if (TREE_CODE (size) == INTEGER_CST && TREE_OVERFLOW (size))
|
||||
size = size_binop (MULT_EXPR,
|
||||
fold_convert (bitsizetype, TYPE_MAX_VALUE (ssizetype)),
|
||||
build_int_cst (bitsizetype, BITS_PER_UNIT));
|
||||
{
|
||||
size
|
||||
= size_binop (MULT_EXPR,
|
||||
fold_convert (bitsizetype, TYPE_MAX_VALUE (ssizetype)),
|
||||
build_int_cst (bitsizetype, BITS_PER_UNIT));
|
||||
size = round_down (size, align);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
14
gcc/testsuite/gnat.dg/addr16.adb
Normal file
14
gcc/testsuite/gnat.dg/addr16.adb
Normal file
@ -0,0 +1,14 @@
|
||||
-- { dg-do compile }
|
||||
|
||||
with Addr16_Pkg; use Addr16_Pkg;
|
||||
|
||||
procedure Addr16 (R : Rec) is
|
||||
|
||||
pragma Unsuppress (Alignment_Check);
|
||||
|
||||
B : Integer;
|
||||
for B'Address use R.A'Address;
|
||||
|
||||
begin
|
||||
null;
|
||||
end;
|
9
gcc/testsuite/gnat.dg/addr16_pkg.ads
Normal file
9
gcc/testsuite/gnat.dg/addr16_pkg.ads
Normal file
@ -0,0 +1,9 @@
|
||||
package Addr16_Pkg is
|
||||
|
||||
type Arr is array (Positive range <>) of Long_Long_Integer;
|
||||
|
||||
type Rec (D : Positive) is record
|
||||
A : Arr (1 .. D);
|
||||
end record;
|
||||
|
||||
end Addr16_Pkg;
|
Loading…
Reference in New Issue
Block a user