From: Eric Botcazou <ebotca...@adacore.com> The recent removal of the unconditional call to Remove_Side_Effects on the expression of an object declaration or an allocator with a class-wide type has introduced a pessimization in the former case for function calls that return a specific tagged type, because the object ultimately created on the primary stack has changed from being of a specific tagged type to being of the class-wide type, the latter type always formally requiring finalization.
With the current finalization machinery, this means that a dispatching call to the Deep_Finalize routine is generated, which is unnecessary. Although this is a generic finalization issue with class-wide objects, this restores the previous behavior in this case to fix the pessimization for now. gcc/ada/ * exp_ch3.adb (Expand_N_Object_Declaration): For a class-wide non- interface stand-alone object initialized by a function call, call Remove_Side_Effects on the expression to capture the result. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/exp_ch3.adb | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb index 6bc76aec5d1..6886bde7bd1 100644 --- a/gcc/ada/exp_ch3.adb +++ b/gcc/ada/exp_ch3.adb @@ -7797,6 +7797,25 @@ package body Exp_Ch3 is -- Common case of explicit object initialization else + -- Small optimization: if the expression is a function call and + -- the object is stand-alone, not declared at library level and of + -- a class-wide type, then we capture the result of the call into + -- a temporary, with the benefit that, if the result's type does + -- not need finalization, nothing will be finalized and, if it + -- does, the temporary only will be finalized by means of a direct + -- call to the Finalize primitive if the result's type is not a + -- class-wide type; whereas, in both cases, the stand-alone object + -- itself would be finalized by means of a dispatching call to the + -- Deep_Finalize routine. + + if Nkind (Expr_Q) = N_Function_Call + and then not Special_Ret_Obj + and then not Is_Library_Level_Entity (Def_Id) + and then Is_Class_Wide_Type (Typ) + then + Remove_Side_Effects (Expr_Q); + end if; + -- In most cases, we must check that the initial value meets any -- constraint imposed by the declared type. However, there is one -- very important exception to this rule. If the entity has an -- 2.34.1