This patch improves on the performance of an object initialization with a build-in-place function call, when the return type is not a definite type but has only access discriminants and no controlled components.
THe following must execute quietly: gcc -c -gnatDG p.adb grep secondary_stack p.adb.dg --- with Discrim; use Discrim; procedure P is I : aliased Integer; A_Obj : A_Type := Create (I'Access); begin null; end; --- package Discrim is type A_Type (IA : access Integer) is limited private; function Create (I : access Integer) return A_Type; private type A_Type (IA : access Integer) is limited record Not_Dependent_On_IA : Boolean; end record; end; --- package body Discrim is function Create (I : access Integer) return A_Type is begin return A : A_Type (I) do A.Not_Dependent_On_IA := False; end return; end; end; Tested on x86_64-pc-linux-gnu, committed on trunk 2016-04-27 Ed Schonberg <schonb...@adacore.com> * exp_ch6.adb (Make_Build_In_Place_Call_In_Object_Declaration): If the return type is an untagged limited record with only access discriminants and no controlled components, the return value does not need to use the secondary stack.
Index: exp_ch6.adb =================================================================== --- exp_ch6.adb (revision 235482) +++ exp_ch6.adb (working copy) @@ -7783,7 +7783,12 @@ Result_Subt : Entity_Id; Definite : Boolean; - -- True for definite function result subtype + -- True if result subtype is definite, or has a size that does not + -- require secondary stack usage (i.e. no variant part or components + -- whose type depends on discriminants). In particular, untagged types + -- with only access discriminants do not require secondary stack use. + -- Note that if the return type is tagged we must always use the sec. + -- stack because the call may dispatch on result. begin -- Step past qualification or unchecked conversion (the latter can occur @@ -7818,7 +7823,10 @@ end if; Result_Subt := Etype (Function_Id); - Definite := Is_Definite_Subtype (Underlying_Type (Result_Subt)); + Definite := + (Is_Definite_Subtype (Underlying_Type (Result_Subt)) + and then not Is_Tagged_Type (Result_Subt)) + or else not Requires_Transient_Scope (Underlying_Type (Result_Subt)); -- Create an access type designating the function's result subtype. We -- use the type of the original call because it may be a call to an