diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2023-10-20 10:26:23 +0200 |
---|---|---|
committer | Marc Poulhiès <poulhies@adacore.com> | 2023-11-21 10:57:43 +0100 |
commit | 4d011701c074cac9bab7edfcf07c1868f0472177 (patch) | |
tree | 0a05cc16cafb2598cf180bf1b2cdf47d88846099 | |
parent | 1f61f81d6ce2fe9c0ee0d833d216b848e0ad0ae4 (diff) | |
download | gcc-4d011701c074cac9bab7edfcf07c1868f0472177.zip gcc-4d011701c074cac9bab7edfcf07c1868f0472177.tar.gz gcc-4d011701c074cac9bab7edfcf07c1868f0472177.tar.bz2 |
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) <E_Array_Subtype>: 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.
-rw-r--r-- | gcc/ada/gcc-interface/decl.cc | 12 | ||||
-rw-r--r-- | 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 9c7f684..c446b14 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 8b2c7f9..e7b5c77 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 |