diff options
Diffstat (limited to 'gcc/ada/gcc-interface')
-rw-r--r-- | gcc/ada/gcc-interface/ada-builtin-types.def | 3 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/ada-builtins.def | 3 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/ada-tree.h | 5 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/decl.cc | 6 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/trans.cc | 8 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/utils2.cc | 41 |
6 files changed, 53 insertions, 13 deletions
diff --git a/gcc/ada/gcc-interface/ada-builtin-types.def b/gcc/ada/gcc-interface/ada-builtin-types.def index f00845b..000d429 100644 --- a/gcc/ada/gcc-interface/ada-builtin-types.def +++ b/gcc/ada/gcc-interface/ada-builtin-types.def @@ -1,7 +1,7 @@ /* This file contains the type definitions for the builtins exclusively used in the GNU Ada compiler. - Copyright (C) 2019 Free Software Foundation, Inc. + Copyright (C) 2019-2022 Free Software Foundation, Inc. This file is part of GCC. @@ -22,4 +22,5 @@ along with GCC; see the file COPYING3. If not see /* See builtin-types.def for details. */ DEF_FUNCTION_TYPE_1 (BT_FN_BOOL_BOOL, BT_BOOL, BT_BOOL) +DEF_FUNCTION_TYPE_1 (BT_FN_PTR_SSIZE, BT_PTR, BT_SSIZE) DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_BOOL_BOOL, BT_BOOL, BT_BOOL, BT_BOOL) diff --git a/gcc/ada/gcc-interface/ada-builtins.def b/gcc/ada/gcc-interface/ada-builtins.def index dcdc4d9..8ba89a8 100644 --- a/gcc/ada/gcc-interface/ada-builtins.def +++ b/gcc/ada/gcc-interface/ada-builtins.def @@ -1,7 +1,7 @@ /* This file contains the definitions for the builtins exclusively used in the GNU Ada compiler. - Copyright (C) 2019 Free Software Foundation, Inc. + Copyright (C) 2019-2022 Free Software Foundation, Inc. This file is part of GCC. @@ -28,3 +28,4 @@ along with GCC; see the file COPYING3. If not see DEF_ADA_BUILTIN (BUILT_IN_EXPECT, "expect", BT_FN_BOOL_BOOL_BOOL, ATTR_CONST_NOTHROW_LEAF_LIST) DEF_ADA_BUILTIN (BUILT_IN_LIKELY, "likely", BT_FN_BOOL_BOOL, ATTR_CONST_NOTHROW_LEAF_LIST) DEF_ADA_BUILTIN (BUILT_IN_UNLIKELY, "unlikely", BT_FN_BOOL_BOOL, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_ADA_BUILTIN (BUILT_IN_RETURN_SLOT, "return_slot", BT_FN_PTR_SSIZE, ATTR_CONST_NOTHROW_LEAF_LIST) diff --git a/gcc/ada/gcc-interface/ada-tree.h b/gcc/ada/gcc-interface/ada-tree.h index 0ec81bc..ca718f4 100644 --- a/gcc/ada/gcc-interface/ada-tree.h +++ b/gcc/ada/gcc-interface/ada-tree.h @@ -577,5 +577,6 @@ do { \ /* Small kludge to be able to define Ada built-in functions locally. We overload them on top of the C++ coroutines builtin functions. */ -#define BUILT_IN_LIKELY BUILT_IN_CORO_PROMISE -#define BUILT_IN_UNLIKELY BUILT_IN_CORO_RESUME +#define BUILT_IN_LIKELY BUILT_IN_CORO_PROMISE +#define BUILT_IN_UNLIKELY BUILT_IN_CORO_RESUME +#define BUILT_IN_RETURN_SLOT BUILT_IN_CORO_DESTROY diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc index e6f2df8..c096b0d 100644 --- a/gcc/ada/gcc-interface/decl.cc +++ b/gcc/ada/gcc-interface/decl.cc @@ -5838,10 +5838,8 @@ gnat_to_gnu_subprog_type (Entity_Id gnat_subprog, bool definition, return_unconstrained_p = true; } - /* Likewise, if the return type requires a transient scope, the return - value will also be allocated on the secondary stack so the actual - return type is the reference type. */ - else if (Requires_Transient_Scope (gnat_return_type)) + /* This is for the other types returned on the secondary stack. */ + else if (Returns_On_Secondary_Stack (gnat_return_type)) { gnu_return_type = build_reference_type (gnu_return_type); return_unconstrained_p = true; diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc index 57a9dee..b8a0d5d 100644 --- a/gcc/ada/gcc-interface/trans.cc +++ b/gcc/ada/gcc-interface/trans.cc @@ -7456,6 +7456,14 @@ gnat_to_gnu (Node_Id gnat_node) gnu_ret_obj); gnu_result = build2 (INIT_EXPR, void_type_node, gnu_ret_deref, gnu_ret_val); + /* Avoid a useless copy with __builtin_return_slot. */ + if (TREE_CODE (gnu_ret_val) == INDIRECT_REF) + gnu_result + = build3 (COND_EXPR, void_type_node, + fold_build2 (NE_EXPR, boolean_type_node, + TREE_OPERAND (gnu_ret_val, 0), + gnu_ret_obj), + gnu_result, NULL_TREE); add_stmt_with_node (gnu_result, gnat_node); gnu_ret_val = NULL_TREE; } diff --git a/gcc/ada/gcc-interface/utils2.cc b/gcc/ada/gcc-interface/utils2.cc index 76622da..ae81a0d 100644 --- a/gcc/ada/gcc-interface/utils2.cc +++ b/gcc/ada/gcc-interface/utils2.cc @@ -2141,9 +2141,9 @@ build_call_alloc_dealloc_proc (tree gnu_obj, tree gnu_size, tree gnu_type, tree gnu_proc = gnat_to_gnu (gnat_proc); tree gnu_call; - /* A storage pool's underlying type is a record type (for both predefined - storage pools and GNAT simple storage pools). The secondary stack uses - the same mechanism, but its pool object (SS_Pool) is an integer. */ + /* A storage pool's underlying type is a record type for both predefined + storage pools and GNAT simple storage pools. The return and secondary + stacks use the same mechanism, but their pool object is an integer. */ if (Is_Record_Type (Underlying_Type (Etype (gnat_pool)))) { /* The size is the third parameter; the alignment is the @@ -2170,7 +2170,6 @@ build_call_alloc_dealloc_proc (tree gnu_obj, tree gnu_size, tree gnu_type, gnu_size, gnu_align); } - /* Secondary stack case. */ else { /* The size is the second parameter. */ @@ -2180,10 +2179,42 @@ build_call_alloc_dealloc_proc (tree gnu_obj, tree gnu_size, tree gnu_type, gnu_size = convert (gnu_size_type, gnu_size); + if (DECL_BUILT_IN_CLASS (gnu_proc) == BUILT_IN_FRONTEND + && DECL_FE_FUNCTION_CODE (gnu_proc) == BUILT_IN_RETURN_SLOT) + { + /* This must be an allocation of the return stack in a function that + returns by invisible reference. */ + gcc_assert (!gnu_obj); + gcc_assert (current_function_decl + && TREE_ADDRESSABLE (TREE_TYPE (current_function_decl))); + tree gnu_ret_size; + + gnu_call = DECL_RESULT (current_function_decl); + + /* The allocation has alreay 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 + = TYPE_SIZE_UNIT + (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (gnu_call))))); + else + gnu_ret_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (gnu_call))); + + gnu_call + = fold_build3 (COND_EXPR, TREE_TYPE (gnu_call), + fold_build2 (LE_EXPR, boolean_type_node, + fold_convert (sizetype, gnu_size), + gnu_ret_size), + gnu_call, + build_call_raise (PE_Explicit_Raise, Empty, + N_Raise_Program_Error)); + } + /* The first arg is the address of the object, for a deallocator, then the size. */ - if (gnu_obj) + else if (gnu_obj) 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); } |