From 88795e14ae7143bd8039af68d2d876ae34568799 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 28 Sep 2020 09:00:46 +0200 Subject: [PATCH] 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. --- gcc/ada/gcc-interface/decl.c | 28 ++++++++++++++++++++-------- gcc/testsuite/gnat.dg/addr16.adb | 14 ++++++++++++++ gcc/testsuite/gnat.dg/addr16_pkg.ads | 9 +++++++++ 3 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/addr16.adb create mode 100644 gcc/testsuite/gnat.dg/addr16_pkg.ads diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index c9c2a95170f..cd0a50b2083 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -232,7 +232,7 @@ static tree build_position_list (tree, bool, tree, tree, unsigned int, tree); static vec build_subst_list (Entity_Id, Entity_Id, bool); static vec build_variant_list (tree, Node_Id, vec, vec); -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; } diff --git a/gcc/testsuite/gnat.dg/addr16.adb b/gcc/testsuite/gnat.dg/addr16.adb new file mode 100644 index 00000000000..8f09da023fb --- /dev/null +++ b/gcc/testsuite/gnat.dg/addr16.adb @@ -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; diff --git a/gcc/testsuite/gnat.dg/addr16_pkg.ads b/gcc/testsuite/gnat.dg/addr16_pkg.ads new file mode 100644 index 00000000000..9a1b9e3b21b --- /dev/null +++ b/gcc/testsuite/gnat.dg/addr16_pkg.ads @@ -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; -- 2.30.2