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.  */

Reply via email to