* 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:
sergei 2013-12-13 19:54:46 +00:00
parent c88be4550d
commit 6ea9ce1077
2 changed files with 12 additions and 28 deletions

View File

@ -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);

View File

@ -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