mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 05:49:12 +02:00
* Mantis #27044: copy Variant to temp if it cannot be passed by reference to fpc_dispinvoke_variant helper. This provides behavior consistent to implicit 'self' parameter of objects/records.
git-svn-id: trunk@29093 -
This commit is contained in:
parent
d844025ddf
commit
64af966eaa
@ -336,6 +336,8 @@ implementation
|
|||||||
pvardatadef : tdef;
|
pvardatadef : tdef;
|
||||||
useresult: boolean;
|
useresult: boolean;
|
||||||
restype: byte;
|
restype: byte;
|
||||||
|
selftemp: ttempcreatenode;
|
||||||
|
selfpara: tnode;
|
||||||
|
|
||||||
names : ansistring;
|
names : ansistring;
|
||||||
variantdispatch : boolean;
|
variantdispatch : boolean;
|
||||||
@ -369,7 +371,7 @@ implementation
|
|||||||
if is_interfacecom_or_dispinterface(sourcedef) then
|
if is_interfacecom_or_dispinterface(sourcedef) then
|
||||||
begin
|
begin
|
||||||
{ distinct IDispatch and IUnknown interfaces }
|
{ distinct IDispatch and IUnknown interfaces }
|
||||||
if def_is_related(tobjectdef(sourcedef),tobjectdef(search_system_type('IDISPATCH').typedef)) then
|
if def_is_related(tobjectdef(sourcedef),interface_idispatch) then
|
||||||
result:=vardispatch
|
result:=vardispatch
|
||||||
else
|
else
|
||||||
result:=varunknown;
|
result:=varunknown;
|
||||||
@ -382,6 +384,8 @@ implementation
|
|||||||
variantdispatch:=selfnode.resultdef.typ=variantdef;
|
variantdispatch:=selfnode.resultdef.typ=variantdef;
|
||||||
result:=internalstatements(statements);
|
result:=internalstatements(statements);
|
||||||
result_data:=nil;
|
result_data:=nil;
|
||||||
|
selftemp:=nil;
|
||||||
|
selfpara:=nil;
|
||||||
|
|
||||||
useresult := assigned(resultdef) and not is_void(resultdef);
|
useresult := assigned(resultdef) and not is_void(resultdef);
|
||||||
if useresult then
|
if useresult then
|
||||||
@ -527,13 +531,27 @@ implementation
|
|||||||
{ actual call }
|
{ actual call }
|
||||||
vardatadef:=trecorddef(search_system_type('TVARDATA').typedef);
|
vardatadef:=trecorddef(search_system_type('TVARDATA').typedef);
|
||||||
|
|
||||||
|
{ the Variant should behave similar to hidden 'self' parameter of objects/records,
|
||||||
|
see issues #26773 and #27044 }
|
||||||
|
if not valid_for_var(selfnode,false) then
|
||||||
|
begin
|
||||||
|
selftemp:=ctempcreatenode.create(selfnode.resultdef,selfnode.resultdef.size,tt_persistent,false);
|
||||||
|
addstatement(statements,selftemp);
|
||||||
|
addstatement(statements,cassignmentnode.create(ctemprefnode.create(selftemp),selfnode));
|
||||||
|
selfpara:=ctemprefnode.create(selftemp);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
selfpara:=selfnode;
|
||||||
|
|
||||||
addstatement(statements,ccallnode.createintern('fpc_dispinvoke_variant',
|
addstatement(statements,ccallnode.createintern('fpc_dispinvoke_variant',
|
||||||
{ parameters are passed always reverted, i.e. the last comes first }
|
{ parameters are passed always reverted, i.e. the last comes first }
|
||||||
ccallparanode.create(caddrnode.create(ctemprefnode.create(params)),
|
ccallparanode.create(caddrnode.create(ctemprefnode.create(params)),
|
||||||
ccallparanode.create(caddrnode.create(calldescnode),
|
ccallparanode.create(caddrnode.create(calldescnode),
|
||||||
ccallparanode.create(ctypeconvnode.create_internal(selfnode,vardatadef),
|
ccallparanode.create(ctypeconvnode.create_internal(selfpara,vardatadef),
|
||||||
ccallparanode.create(ctypeconvnode.create_internal(resultvalue,pvardatadef),nil)))))
|
ccallparanode.create(ctypeconvnode.create_internal(resultvalue,pvardatadef),nil)))))
|
||||||
);
|
);
|
||||||
|
if assigned(selftemp) then
|
||||||
|
addstatement(statements,ctempdeletenode.create(selftemp));
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
|
Loading…
Reference in New Issue
Block a user