mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-07 12:50:31 +02:00
* force pointer-based self parameters of inlined routines in temps for LLVM
to ensure that their type gets updated git-svn-id: trunk@40631 -
This commit is contained in:
parent
3ccc3e329b
commit
eb769e3859
@ -27,7 +27,7 @@ interface
|
||||
|
||||
uses
|
||||
parabase,
|
||||
ncgcal,
|
||||
ncal,ncgcal,
|
||||
cgutils;
|
||||
|
||||
type
|
||||
@ -38,6 +38,7 @@ interface
|
||||
|
||||
tllvmcallnode = class(tcgcallnode)
|
||||
protected
|
||||
function paraneedsinlinetemp(para: tcallparanode; const pushconstaddr, complexpara: boolean): boolean; override;
|
||||
function can_call_ref(var ref: treference): boolean; override;
|
||||
procedure pushparas; override;
|
||||
end;
|
||||
@ -47,7 +48,7 @@ implementation
|
||||
|
||||
uses
|
||||
verbose,
|
||||
ncal;
|
||||
symconst,symdef;
|
||||
|
||||
{*****************************************************************************
|
||||
TLLVMCALLPARANODE
|
||||
@ -64,6 +65,25 @@ implementation
|
||||
TLLVMCALLNODE
|
||||
*****************************************************************************}
|
||||
|
||||
function tllvmcallnode.paraneedsinlinetemp(para: tcallparanode; const pushconstaddr, complexpara: boolean): boolean;
|
||||
begin
|
||||
{ We don't insert type conversions for self node trees to the type of
|
||||
the self parameter (and doing so is quite hard due to all kinds of
|
||||
ugly hacks with this parameter). This means that if we pass on a
|
||||
self parameter through multiple levels of inlining, it may no
|
||||
longer match the actual type of the parameter it has been passed to
|
||||
-> always store in a temp which by definition will have the right
|
||||
type (if it's a pointer-like type) }
|
||||
if (vo_is_self in para.parasym.varoptions) and
|
||||
(is_class_or_interface_or_dispinterface(para.parasym.vardef) or
|
||||
is_classhelper(para.parasym.vardef) or
|
||||
((para.parasym.vardef.typ=classrefdef) and
|
||||
is_class(tclassrefdef(para.parasym.vardef).pointeddef))) then
|
||||
result:=true
|
||||
else
|
||||
result:=inherited;
|
||||
end;
|
||||
|
||||
function tllvmcallnode.can_call_ref(var ref: treference): boolean;
|
||||
begin
|
||||
result:=false;
|
||||
|
@ -108,6 +108,7 @@ interface
|
||||
it's not strictly necessary) for speed and code size reasons.
|
||||
Returns true if the temp creation has been handled, false otherwise
|
||||
}
|
||||
function paraneedsinlinetemp(para: tcallparanode; const pushconstaddr, complexpara: boolean): boolean; virtual;
|
||||
function maybecreateinlineparatemp(para: tcallparanode; out complexpara: boolean): boolean;
|
||||
procedure createinlineparas;
|
||||
procedure wrapcomplexinlinepara(para: tcallparanode); virtual;
|
||||
@ -4624,14 +4625,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function tcallnode.maybecreateinlineparatemp(para: tcallparanode; out complexpara: boolean): boolean;
|
||||
var
|
||||
tempnode: ttempcreatenode;
|
||||
realtarget: tnode;
|
||||
paracomplexity: longint;
|
||||
pushconstaddr: boolean;
|
||||
|
||||
function needtemp: boolean;
|
||||
function tcallnode.paraneedsinlinetemp(para: tcallparanode; const pushconstaddr, complexpara: boolean): boolean;
|
||||
begin
|
||||
{ We need a temp if the passed value will not be in memory, while
|
||||
the parameter inside the routine must be in memory }
|
||||
@ -4716,6 +4710,13 @@ implementation
|
||||
result:=false;
|
||||
end;
|
||||
|
||||
|
||||
function tcallnode.maybecreateinlineparatemp(para: tcallparanode; out complexpara: boolean): boolean;
|
||||
var
|
||||
tempnode: ttempcreatenode;
|
||||
realtarget: tnode;
|
||||
paracomplexity: longint;
|
||||
pushconstaddr: boolean;
|
||||
begin
|
||||
result:=false;
|
||||
{ determine how a parameter is passed to the inlined body
|
||||
@ -4773,7 +4774,7 @@ implementation
|
||||
{ check if we have to create a temp, assign the parameter's
|
||||
contents to that temp and then substitute the parameter
|
||||
with the temp everywhere in the function }
|
||||
if needtemp then
|
||||
if paraneedsinlinetemp(para,pushconstaddr,complexpara) then
|
||||
begin
|
||||
tempnode:=ctempcreatenode.create(para.parasym.vardef,para.parasym.vardef.size,
|
||||
tt_persistent,tparavarsym(para.parasym).is_regvar(false));
|
||||
|
Loading…
Reference in New Issue
Block a user