From 4d011701c074cac9bab7edfcf07c1868f0472177 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 20 Oct 2023 10:26:23 +0200 Subject: [PATCH] ada: Fix issue with indefinite vector of overaligned unconstrained array The problem is that the aligning machinery is not consistently triggered, depending on whether a constrained view or the nominal unconstrained view of the element type is used to perform the allocations and deallocations. gcc/ada/ * gcc-interface/decl.cc (gnat_to_gnu_entity) : Put the alignment directly on the type in the constrained case too. * gcc-interface/utils.cc (maybe_pad_type): For an array type, take the alignment of the element type as the original alignment. --- gcc/ada/gcc-interface/decl.cc | 12 ++++++++++++ gcc/ada/gcc-interface/utils.cc | 19 ++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc index 9c7f6840e21..c446b146179 100644 --- a/gcc/ada/gcc-interface/decl.cc +++ b/gcc/ada/gcc-interface/decl.cc @@ -3010,6 +3010,18 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) TREE_TYPE (TYPE_FIELDS (gnu_type)) = gnu_inner; } } + + /* Otherwise, if an alignment is specified, use it if valid and, if + the alignment was requested with an explicit clause, state so. */ + else if (Known_Alignment (gnat_entity)) + { + SET_TYPE_ALIGN (gnu_type, + validate_alignment (Alignment (gnat_entity), + gnat_entity, + TYPE_ALIGN (gnu_type))); + if (Present (Alignment_Clause (gnat_entity))) + TYPE_USER_ALIGN (gnu_type) = 1; + } } break; diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc index 8b2c7f99ef3..e7b5c7783b1 100644 --- a/gcc/ada/gcc-interface/utils.cc +++ b/gcc/ada/gcc-interface/utils.cc @@ -1485,7 +1485,14 @@ canonicalize_pad_type (tree type) IS_COMPONENT_TYPE is true if this is being done for the component type of an array. DEFINITION is true if this type is being defined. SET_RM_SIZE is true if the RM size of the resulting type is to be set to SIZE too; in - this case, the padded type is canonicalized before being returned. */ + this case, the padded type is canonicalized before being returned. + + Note that, if TYPE is an array, then we pad it even if it has already got + an alignment of ALIGN, provided that it's larger than the alignment of the + element type. This ensures that the size of the type is a multiple of its + alignment as required by the GCC type system, and alleviates the oddity of + the larger alignment, which is used to implement alignment clauses present + on unconstrained array types. */ tree maybe_pad_type (tree type, tree size, unsigned int align, @@ -1493,7 +1500,10 @@ maybe_pad_type (tree type, tree size, unsigned int align, bool definition, bool set_rm_size) { tree orig_size = TYPE_SIZE (type); - unsigned int orig_align = TYPE_ALIGN (type); + unsigned int orig_align + = TREE_CODE (type) == ARRAY_TYPE + ? TYPE_ALIGN (TREE_TYPE (type)) + : TYPE_ALIGN (type); tree record, field; /* If TYPE is a padded type, see if it agrees with any size and alignment @@ -1515,7 +1525,10 @@ maybe_pad_type (tree type, tree size, unsigned int align, type = TREE_TYPE (TYPE_FIELDS (type)); orig_size = TYPE_SIZE (type); - orig_align = TYPE_ALIGN (type); + orig_align + = TREE_CODE (type) == ARRAY_TYPE + ? TYPE_ALIGN (TREE_TYPE (type)) + : TYPE_ALIGN (type); } /* If the size is either not being changed or is being made smaller (which -- 2.11.4.GIT