diff --git a/compiler/aarch64/cpupara.pas b/compiler/aarch64/cpupara.pas index c08a9e3e8f..9812fc3db2 100644 --- a/compiler/aarch64/cpupara.pas +++ b/compiler/aarch64/cpupara.pas @@ -201,15 +201,8 @@ unit cpupara; sym: tsym; fpufield: boolean; begin - { this must be system independent safecall and record constructor result - is always return in param } - if (tf_safecall_exceptions in target_info.flags) and - (pd.proccalloption=pocall_safecall) or - ((pd.proctypeoption=potype_constructor)and is_record(def)) then - begin - result:=true; - exit; - end; + if handle_common_ret_in_param(def,pd,result) then + exit; case def.typ of recorddef: begin diff --git a/compiler/arm/cpupara.pas b/compiler/arm/cpupara.pas index 8d05c50b52..ab7c04dc87 100644 --- a/compiler/arm/cpupara.pas +++ b/compiler/arm/cpupara.pas @@ -207,15 +207,8 @@ unit cpupara; sym: tsym; fpufield: boolean; begin - { this must be system independent safecall and record constructor result - is always return in param } - if (tf_safecall_exceptions in target_info.flags) and - (pd.proccalloption=pocall_safecall) or - ((pd.proctypeoption=potype_constructor)and is_record(def)) then - begin - result:=true; - exit; - end; + if handle_common_ret_in_param(def,pd,result) then + exit; case def.typ of recorddef: begin diff --git a/compiler/avr/cpupara.pas b/compiler/avr/cpupara.pas index a9d6a7b2ab..5e8a1506d6 100644 --- a/compiler/avr/cpupara.pas +++ b/compiler/avr/cpupara.pas @@ -182,15 +182,8 @@ unit cpupara; function tavrparamanager.ret_in_param(def:tdef;pd:tabstractprocdef):boolean; begin - { this must be system independent safecall and record constructor result - is always return in param } - if (tf_safecall_exceptions in target_info.flags) and - (pd.proccalloption=pocall_safecall) or - ((pd.proctypeoption=potype_constructor)and is_record(def)) then - begin - result:=true; - exit; - end; + if handle_common_ret_in_param(def,pd,result) then + exit; case def.typ of recorddef: { this is how gcc 4.0.4 on linux seems to do it, it doesn't look like being diff --git a/compiler/i386/cpupara.pas b/compiler/i386/cpupara.pas index aaf26db55c..00f94496af 100644 --- a/compiler/i386/cpupara.pas +++ b/compiler/i386/cpupara.pas @@ -96,15 +96,8 @@ unit cpupara; var size: longint; begin - { this must be system independent safecall and record constructor result - is always return in param } - if (tf_safecall_exceptions in target_info.flags) and - (pd.proccalloption=pocall_safecall) or - ((pd.proctypeoption=potype_constructor)and is_record(def)) then - begin - result:=true; - exit; - end; + if handle_common_ret_in_param(def,pd,result) then + exit; case target_info.system of system_i386_win32 : begin diff --git a/compiler/ncgcal.pas b/compiler/ncgcal.pas index f03ffae1be..376f7e85c1 100644 --- a/compiler/ncgcal.pas +++ b/compiler/ncgcal.pas @@ -379,8 +379,7 @@ implementation begin { Check that the return location is set when the result is passed in a parameter } - if ((procdefinition.proctypeoption<>potype_constructor)or is_record(resultdef)) and - paramanager.ret_in_param(resultdef,procdefinition) then + if paramanager.ret_in_param(resultdef,procdefinition) then begin { self.location is set near the end of secondcallparan so it refers to the implicit result parameter } diff --git a/compiler/paramgr.pas b/compiler/paramgr.pas index 06cb772680..5a60b087b0 100644 --- a/compiler/paramgr.pas +++ b/compiler/paramgr.pas @@ -144,6 +144,11 @@ unit paramgr; { common part of get_funcretloc; returns true if retloc is completely initialized afterwards } function set_common_funcretloc_info(p : tabstractprocdef; forcetempdef: tdef; out retcgsize: tcgsize; out retloc: tcgpara): boolean; + { common part of ret_in_param; is called by ret_in_param at the + beginning and every tparamanager descendant can decide to call it + itself as well; parameter retinparam is only valid if function + returns true } + function handle_common_ret_in_param(def:tdef;pd:tabstractprocdef;out retinparam:boolean):boolean; end; @@ -168,15 +173,8 @@ implementation { true if uses a parameter as return value } function tparamanager.ret_in_param(def:tdef;pd:tabstractprocdef):boolean; begin - { this must be system independent safecall and record constructor result - is always return in param } - if (tf_safecall_exceptions in target_info.flags) and - (pd.proccalloption=pocall_safecall) or - ((pd.proctypeoption=potype_constructor)and is_record(def)) then - begin - result:=true; - exit; - end; + if handle_common_ret_in_param(def,pd,result) then + exit; ret_in_param:=((def.typ=arraydef) and not(is_dynamic_array(def))) or (def.typ=recorddef) or (def.typ=stringdef) or @@ -566,6 +564,26 @@ implementation result:=false; end; + function tparamanager.handle_common_ret_in_param(def: tdef; + pd: tabstractprocdef; out retinparam: boolean): boolean; + begin + { this must be system independent safecall and record constructor result + is always return in param } + if (tf_safecall_exceptions in target_info.flags) and + (pd.proccalloption=pocall_safecall) or + ((pd.proctypeoption=potype_constructor)and is_record(def)) then + begin + retinparam:=true; + exit(true); + end; + if pd.proctypeoption=potype_constructor then + begin + retinparam:=false; + exit(true); + end; + result:=false; + end; + initialization ; finalization diff --git a/compiler/x86_64/cpupara.pas b/compiler/x86_64/cpupara.pas index 03cee1679b..20b4b5f1b4 100644 --- a/compiler/x86_64/cpupara.pas +++ b/compiler/x86_64/cpupara.pas @@ -623,15 +623,8 @@ unit cpupara; classes: tx64paraclasses; numclasses: longint; begin - { this must be system independent safecall and record constructor result - is always return in param } - if (tf_safecall_exceptions in target_info.flags) and - (pd.proccalloption=pocall_safecall) or - ((pd.proctypeoption=potype_constructor)and is_record(def)) then - begin - result:=true; - exit; - end; + if handle_common_ret_in_param(def,pd,result) then + exit; case def.typ of { for records it depends on their contents and size } recorddef,