]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ada: Make detection of useless copy for return more robust
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 12 Mar 2024 16:56:00 +0000 (17:56 +0100)
committerMarc Poulhiès <poulhies@adacore.com>
Tue, 21 May 2024 07:27:57 +0000 (09:27 +0200)
In the return-by-invisible-reference case, the return object of an extended
return statement is allocated directly on the return stack and, therefore,
the copy operation on return is useless.  The code detecting this was not
robust enough and missed some complex cases.

gcc/ada/

* gcc-interface/trans.cc (gnat_to_gnu) <N_Simple_Return_Statement>:
In the return-by-invisible-reference case, remove conversions before
looking for a dereference in the return values and building the test
protecting against a useless copy operation.

gcc/ada/gcc-interface/trans.cc

index a6b86ec8b511c90f00c3d3c34c083990cf273e54..4ae599b8b4c5cff7cd04642927dac0856588b3b8 100644 (file)
@@ -7767,11 +7767,12 @@ gnat_to_gnu (Node_Id gnat_node)
                gnu_result = build2 (INIT_EXPR, void_type_node,
                                     gnu_ret_deref, gnu_ret_val);
                /* Avoid a useless copy with __builtin_return_slot.  */
-               if (INDIRECT_REF_P (gnu_ret_val))
+               tree gnu_inner_val = remove_conversions (gnu_ret_val, false);
+               if (INDIRECT_REF_P (gnu_inner_val))
                  gnu_result
                    = build3 (COND_EXPR, void_type_node,
                              fold_build2 (NE_EXPR, boolean_type_node,
-                                          TREE_OPERAND (gnu_ret_val, 0),
+                                          TREE_OPERAND (gnu_inner_val, 0),
                                           gnu_ret_obj),
                              gnu_result, NULL_TREE);
                add_stmt_with_node (gnu_result, gnat_node);