From 3202e9f88fd286a8fc4814abeaa2238d70f4d585 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Poulhi=C3=A8s?= Date: Thu, 2 Jun 2022 09:52:21 +0200 Subject: [Ada] Handle secondary stack memory allocations alignment To accomodate cases where objects allocated on the secondary stack needed a more constrained alignement than Standard'Maximum_Alignement, the alignment for all allocations in the full runtime were forced on to be aligned on Standard'Maximum_Alignement*2. This changes removes this workaround and correctly handles the over-alignment in all runtimes. This change modifies the SS_Allocate procedure to accept a new Alignment parameter and to dynamically realign the pointer returned by the memory allocation (Allocate_* functions or dedicated stack allocations for zfp/cert). It also simplifies the 0-sized allocations by not allocating any memory if pointer is already correctly aligned (already the case in cert and zfp runtimes). gcc/ada/ * libgnat/s-secsta.ads (SS_Allocate): Add new Alignment parameter. (Memory_Alignment): Remove. * libgnat/s-secsta.adb (Align_Addr): New. (SS_Allocate): Add new Alignment parameter. Realign pointer if needed. Don't allocate anything for 0-sized allocations. * gcc-interface/utils2.cc (build_call_alloc_dealloc_proc): Add allocated object's alignment as last parameter to allocation invocation. --- gcc/ada/gcc-interface/utils2.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'gcc/ada/gcc-interface/utils2.cc') diff --git a/gcc/ada/gcc-interface/utils2.cc b/gcc/ada/gcc-interface/utils2.cc index ae81a0d..0dcc9ff 100644 --- a/gcc/ada/gcc-interface/utils2.cc +++ b/gcc/ada/gcc-interface/utils2.cc @@ -2139,6 +2139,8 @@ build_call_alloc_dealloc_proc (tree gnu_obj, tree gnu_size, tree gnu_type, Entity_Id gnat_proc, Entity_Id gnat_pool) { tree gnu_proc = gnat_to_gnu (gnat_proc); + tree gnu_align = size_int (TYPE_ALIGN (gnu_type) / BITS_PER_UNIT); + tree gnu_call; /* A storage pool's underlying type is a record type for both predefined @@ -2154,7 +2156,6 @@ build_call_alloc_dealloc_proc (tree gnu_obj, tree gnu_size, tree gnu_type, tree gnu_pool = gnat_to_gnu (gnat_pool); tree gnu_pool_addr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_pool); - tree gnu_align = size_int (TYPE_ALIGN (gnu_type) / BITS_PER_UNIT); gnu_size = convert (gnu_size_type, gnu_size); gnu_align = convert (gnu_size_type, gnu_align); @@ -2178,6 +2179,7 @@ build_call_alloc_dealloc_proc (tree gnu_obj, tree gnu_size, tree gnu_type, tree gnu_size_type = gnat_to_gnu_type (gnat_size_type); gnu_size = convert (gnu_size_type, gnu_size); + gnu_align = convert (gnu_size_type, gnu_align); if (DECL_BUILT_IN_CLASS (gnu_proc) == BUILT_IN_FRONTEND && DECL_FE_FUNCTION_CODE (gnu_proc) == BUILT_IN_RETURN_SLOT) @@ -2191,7 +2193,7 @@ build_call_alloc_dealloc_proc (tree gnu_obj, tree gnu_size, tree gnu_type, gnu_call = DECL_RESULT (current_function_decl); - /* The allocation has alreay been done by the caller so we check that + /* The allocation has already been done by the caller so we check that we are not going to overflow the return slot. */ if (TYPE_CI_CO_LIST (TREE_TYPE (current_function_decl))) gnu_ret_size @@ -2216,7 +2218,7 @@ build_call_alloc_dealloc_proc (tree gnu_obj, tree gnu_size, tree gnu_type, gnu_call = build_call_n_expr (gnu_proc, 2, gnu_obj, gnu_size); else - gnu_call = build_call_n_expr (gnu_proc, 1, gnu_size); + gnu_call = build_call_n_expr (gnu_proc, 2, gnu_size, gnu_align); } return gnu_call; @@ -2334,7 +2336,7 @@ maybe_wrap_free (tree data_ptr, tree data_type) /* Build a GCC tree to call an allocation or deallocation function. If GNU_OBJ is nonzero, it is an object to deallocate. Otherwise, - generate an allocator. + generate an allocation. GNU_SIZE is the number of bytes to allocate and GNU_TYPE is the contained object type, used to determine the to-be-honored address alignment. -- cgit v1.1