mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 13:49:39 +02:00
* fix #38122 in a more correct way than previously done: instead of adjusting the methodpointer node when it's a deref node adjust what value is stored in a temp if a call node is encountered: store the pointer value, not the pointed to value to avoid the reference getting lost
+ added test (note: the test fails at least on x86_64-win64 due to some different reason :/ )
This commit is contained in:
parent
d18a565e72
commit
50b160651c
@ -2263,6 +2263,7 @@ implementation
|
|||||||
|
|
||||||
procedure tcallnode.load_in_temp(var p:tnode);
|
procedure tcallnode.load_in_temp(var p:tnode);
|
||||||
var
|
var
|
||||||
|
actnode : pnode;
|
||||||
loadp,
|
loadp,
|
||||||
refp : tnode;
|
refp : tnode;
|
||||||
hdef : tdef;
|
hdef : tdef;
|
||||||
@ -2271,6 +2272,21 @@ implementation
|
|||||||
begin
|
begin
|
||||||
if assigned(p) then
|
if assigned(p) then
|
||||||
begin
|
begin
|
||||||
|
{ if the node is a deref node we load the pointer in a temp to allow
|
||||||
|
code using this node to still be able to modify the original
|
||||||
|
reference (e.g. a function returning a floating point value on x86
|
||||||
|
would pass that value through the FP stack and then to the stack
|
||||||
|
and thus e.g. a type helper for float called on that would modify
|
||||||
|
the temporary memory on the stack instead of the returned pointer
|
||||||
|
value }
|
||||||
|
actnode:=@p;
|
||||||
|
actnode:=actualtargetnode(actnode);
|
||||||
|
if actnode^.nodetype=derefn then
|
||||||
|
begin
|
||||||
|
load_in_temp(tderefnode(actnode^).left);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
{ temp create }
|
{ temp create }
|
||||||
usederef:=(p.resultdef.typ in [arraydef,recorddef]) or
|
usederef:=(p.resultdef.typ in [arraydef,recorddef]) or
|
||||||
is_shortstring(p.resultdef) or
|
is_shortstring(p.resultdef) or
|
||||||
@ -4415,24 +4431,6 @@ implementation
|
|||||||
|
|
||||||
if methodpointer.nodetype<>typen then
|
if methodpointer.nodetype<>typen then
|
||||||
begin
|
begin
|
||||||
{ if the value a type helper works on is a derefentiation (before
|
|
||||||
removing postix operators) we need to pass the original pointer
|
|
||||||
as Self as the Self value might be changed by the helper }
|
|
||||||
if is_objectpascal_helper(tdef(procdefinition.owner.defowner)) and
|
|
||||||
not is_implicit_pointer_object_type(tobjectdef(procdefinition.owner.defowner).extendeddef) then
|
|
||||||
begin
|
|
||||||
hpt:=methodpointer;
|
|
||||||
|
|
||||||
hpt:=actualtargetnode(@hpt)^;
|
|
||||||
if hpt.nodetype=derefn then
|
|
||||||
begin
|
|
||||||
tmp:=tderefnode(hpt).left;
|
|
||||||
tderefnode(hpt).left:=nil;
|
|
||||||
methodpointer.free;
|
|
||||||
methodpointer:=tmp;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
hpt:=methodpointer;
|
hpt:=methodpointer;
|
||||||
|
|
||||||
{ Remove all postfix operators }
|
{ Remove all postfix operators }
|
||||||
|
12
tests/webtbs/tw38122c.pp
Normal file
12
tests/webtbs/tw38122c.pp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
program tw38122c;
|
||||||
|
{$mode delphi}
|
||||||
|
uses sysutils;
|
||||||
|
|
||||||
|
var
|
||||||
|
j:integer;
|
||||||
|
begin
|
||||||
|
j:=22;
|
||||||
|
if pinteger(@j)^.tostring <> '22' then
|
||||||
|
halt(1);
|
||||||
|
end.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user