mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-02 19:43:15 +01:00
* Force managed types to be always returned in parameters, independent of target (primitive types were already handled that way; the patch affects small records with fields of managed types).
* Generating code to finalize result on exception at callee side is no longer necessary. git-svn-id: trunk@26228 -
This commit is contained in:
parent
c88be4550d
commit
6ea9ce1077
@ -589,8 +589,10 @@ implementation
|
||||
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 }
|
||||
{ This must be system independent: safecall and record constructor result
|
||||
is always returned in param.
|
||||
Furthermore, any managed type is returned in param, in order to avoid
|
||||
its finalization on exception at callee side. }
|
||||
if (tf_safecall_exceptions in target_info.flags) and
|
||||
(pd.proccalloption=pocall_safecall) or
|
||||
(
|
||||
@ -603,7 +605,7 @@ implementation
|
||||
is_objectpascal_helper(tdef(pd.owner.defowner))
|
||||
)
|
||||
)
|
||||
) then
|
||||
) or is_managed_type(def) then
|
||||
begin
|
||||
retinparam:=true;
|
||||
exit(true);
|
||||
|
||||
@ -651,28 +651,6 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function generate_except_block:tnode;
|
||||
var
|
||||
newstatement : tstatementnode;
|
||||
begin
|
||||
generate_except_block:=internalstatements(newstatement);
|
||||
|
||||
{ a constructor needs call destructor (if available) when it
|
||||
is not inherited }
|
||||
if not assigned(current_structdef) or
|
||||
(current_procinfo.procdef.proctypeoption<>potype_constructor) then
|
||||
begin
|
||||
{ no constructor }
|
||||
{ must be the return value finalized before reraising the exception? }
|
||||
if (not is_void(current_procinfo.procdef.returndef)) and
|
||||
is_managed_type(current_procinfo.procdef.returndef) and
|
||||
(not paramanager.ret_in_param(current_procinfo.procdef.returndef,current_procinfo.procdef)) and
|
||||
(not is_class(current_procinfo.procdef.returndef)) then
|
||||
addstatement(newstatement,cnodeutils.finalize_data_node(load_result_node));
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
TCGProcInfo
|
||||
****************************************************************************}
|
||||
@ -820,7 +798,6 @@ implementation
|
||||
finalcode,
|
||||
bodyentrycode,
|
||||
bodyexitcode,
|
||||
exceptcode,
|
||||
wrappedbody,
|
||||
newblock : tnode;
|
||||
codestatement,
|
||||
@ -864,10 +841,15 @@ implementation
|
||||
not(po_assembler in procdef.procoptions) and
|
||||
not(target_info.system in systems_garbage_collected_managed_types) then
|
||||
begin
|
||||
{ Any result of managed type must be returned in parameter }
|
||||
if is_managed_type(procdef.returndef) and
|
||||
(not paramanager.ret_in_param(procdef.returndef,procdef)) and
|
||||
(not is_class(procdef.returndef)) then
|
||||
InternalError(2013121301);
|
||||
|
||||
{ Generate special exception block only needed when
|
||||
implicit finaly is used }
|
||||
current_filepos:=exitpos;
|
||||
exceptcode:=generate_except_block;
|
||||
{ Generate code that will be in the try...finally }
|
||||
finalcode:=internalstatements(codestatement);
|
||||
addstatement(codestatement,final_asmnode);
|
||||
@ -877,7 +859,7 @@ implementation
|
||||
wrappedbody:=ctryfinallynode.create_implicit(
|
||||
code,
|
||||
finalcode,
|
||||
exceptcode);
|
||||
cnothingnode.create);
|
||||
{ afterconstruction must be called after final_asmnode, because it
|
||||
has to execute after the temps have been finalised in case of a
|
||||
refcounted class (afterconstruction decreases the refcount
|
||||
|
||||
Loading…
Reference in New Issue
Block a user