https://gcc.gnu.org/g:7fcbb81f0c9266147bea509f7c01b1e96f2a171f
commit r17-1211-g7fcbb81f0c9266147bea509f7c01b1e96f2a171f Author: Eric Botcazou <[email protected]> Date: Mon Feb 9 09:40:18 2026 +0100 ada: Adjust RESULT_DECL of functions after updating their profile if needed Adjusting the RESULT_DECL of functions is necessary before handing them over to the middle-end when they return by invisible reference and are defined in the current translation unit, so that's done in Subprogram_Body_to_gnu. That's also needed when the functions are generated by the middle-end, like GNU thunks. But, in this case, the transformation can only be applied when the full view of the type is available, which is not guaranteed by the time maybe_make_gnu_thunk is invoked, so the transformation needs to be delayed and applied by update_profile when the full view is eventually encountered. gcc/ada/ChangeLog: PR ada/89609 * gcc-interface/gigi.h (adjust_result_decl_for_invisible_reference): New inline function. * gcc-interface/decl.cc (update_profile): Adjust the RESULT_DECL of the function if it returns by invisible reference. * gcc-interface/trans.cc (Subprogram_Body_to_gnu): Replace manual adjustment by a call to adjust_result_decl_for_invisible_reference. (maybe_make_gnu_thunk): Likewise. * gcc-interface/targtyps.cc: Include stor-layout.h header file. Diff: --- gcc/ada/gcc-interface/decl.cc | 3 +++ gcc/ada/gcc-interface/gigi.h | 24 ++++++++++++++++++++++++ gcc/ada/gcc-interface/targtyps.cc | 1 + gcc/ada/gcc-interface/trans.cc | 25 ++++--------------------- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc index 7f39113186f0..d9b70019c4a2 100644 --- a/gcc/ada/gcc-interface/decl.cc +++ b/gcc/ada/gcc-interface/decl.cc @@ -6018,6 +6018,9 @@ update_profile (Entity_Id gnat_subprog) DECL_ARGUMENTS (gnu_subprog) = gnu_param_list; finish_subprog_decl (gnu_subprog, gnu_ext_name, gnu_type); + + /* If the function returns by invisible reference, make it explicit. */ + adjust_result_decl_for_invisible_reference (gnu_subprog); } } diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h index 793d7145b5e7..f4d791195187 100644 --- a/gcc/ada/gcc-interface/gigi.h +++ b/gcc/ada/gcc-interface/gigi.h @@ -1208,6 +1208,30 @@ return_type_with_variable_size_p (tree type) return false; } +/* Adjust RESULT_DECL of a function that returns by invisible reference. + + Adjusting the RESULT_DECL of functions is needed before handing them over + to the middle-end when they return by invisible reference and are defined + in the current translation unit, which is done in Subprogram_Body_to_gnu. + + That's also needed when the functions are generated by the middle-end, like + GNU thunks. But, in this case, the transformation can only be applied when + the full view of the type is available, which is not guaranteed by the time + maybe_make_gnu_thunk is invoked, so the transformation needs to be delayed + and applied by update_profile when the full view is eventually seen. */ + +static inline void +adjust_result_decl_for_invisible_reference (tree subprog) +{ + if (TREE_ADDRESSABLE (TREE_TYPE (subprog)) + && TREE_CODE (TREE_TYPE (DECL_RESULT (subprog))) != REFERENCE_TYPE) + { + TREE_TYPE (DECL_RESULT (subprog)) + = build_reference_type (TREE_TYPE (DECL_RESULT (subprog))); + relayout_decl (DECL_RESULT (subprog)); + } +} + /* Return the unsigned version of TYPE_NODE, a scalar type. */ static inline tree diff --git a/gcc/ada/gcc-interface/targtyps.cc b/gcc/ada/gcc-interface/targtyps.cc index 4fc97cfb3fd1..4768322e15ae 100644 --- a/gcc/ada/gcc-interface/targtyps.cc +++ b/gcc/ada/gcc-interface/targtyps.cc @@ -31,6 +31,7 @@ #include "tm.h" #include "target.h" #include "tree.h" +#include "stor-layout.h" #include "ada.h" #include "types.h" diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc index 6eca5a49cd5e..f66d0b99ba3b 100644 --- a/gcc/ada/gcc-interface/trans.cc +++ b/gcc/ada/gcc-interface/trans.cc @@ -3995,17 +3995,8 @@ Subprogram_Body_to_gnu (Node_Id gnat_node) else gnu_return_var_elmt = NULL_TREE; - /* If the function returns by invisible reference, make it explicit in the - function body, but beware that maybe_make_gnu_thunk may already have done - it if the function is inlined across units. See gnat_to_gnu_subprog_type - for more details. */ - if (TREE_ADDRESSABLE (gnu_subprog_type) - && TREE_CODE (TREE_TYPE (gnu_result_decl)) != REFERENCE_TYPE) - { - TREE_TYPE (gnu_result_decl) - = build_reference_type (TREE_TYPE (gnu_result_decl)); - relayout_decl (gnu_result_decl); - } + /* If the function returns by invisible reference, make it explicit. */ + adjust_result_decl_for_invisible_reference (gnu_subprog); /* Set the line number in the decl to correspond to that of the body. */ if (DECL_IGNORED_P (gnu_subprog)) @@ -11514,16 +11505,8 @@ maybe_make_gnu_thunk (Entity_Id gnat_thunk, tree gnu_thunk) indirect_offset = (HOST_WIDE_INT) (POINTER_SIZE / BITS_PER_UNIT); } - /* If the target returns by invisible reference and is external, apply the - same transformation as Subprogram_Body_to_gnu here. */ - if (TREE_ADDRESSABLE (TREE_TYPE (gnu_target)) - && DECL_EXTERNAL (gnu_target) - && TREE_CODE (TREE_TYPE (DECL_RESULT (gnu_target))) != REFERENCE_TYPE) - { - TREE_TYPE (DECL_RESULT (gnu_target)) - = build_reference_type (TREE_TYPE (DECL_RESULT (gnu_target))); - relayout_decl (DECL_RESULT (gnu_target)); - } + /* If the function returns by invisible reference, make it explicit. */ + adjust_result_decl_for_invisible_reference (gnu_target); /* The thunk expander requires the return types of thunk and target to be compatible, which is not fully the case with the CICO mechanism. */
