From: Eric Botcazou Date: Fri, 20 Oct 2023 08:26:23 +0000 (+0200) Subject: ada: Fix issue with indefinite vector of overaligned unconstrained array X-Git-Tag: basepoints/gcc-15~4475 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4d011701c074cac9bab7edfcf07c1868f0472177;p=thirdparty%2Fgcc.git 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. --- diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc index 9c7f6840e210..c446b1461790 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 8b2c7f99ef30..e7b5c7783b1f 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