mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-23 02:18:41 +02:00
* copy the implicit pointer rather than the contents of var/out/constref
implicit pointer types into the nestedfpstruct, so that the original parameter is properly changed when updated from inside nested routines git-svn-id: branches/jvmbackend@19645 -
This commit is contained in:
parent
74510f9069
commit
4dee36b64b
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -9794,6 +9794,7 @@ tests/test/jvm/testshort.pp svneol=native#text/plain
|
|||||||
tests/test/jvm/tformalpara.pp svneol=native#text/plain
|
tests/test/jvm/tformalpara.pp svneol=native#text/plain
|
||||||
tests/test/jvm/tint.pp svneol=native#text/plain
|
tests/test/jvm/tint.pp svneol=native#text/plain
|
||||||
tests/test/jvm/tintstr.pp svneol=native#text/plain
|
tests/test/jvm/tintstr.pp svneol=native#text/plain
|
||||||
|
tests/test/jvm/tnestedset.pp svneol=native#text/plain
|
||||||
tests/test/jvm/tnestproc.pp svneol=native#text/plain
|
tests/test/jvm/tnestproc.pp svneol=native#text/plain
|
||||||
tests/test/jvm/tprop.pp svneol=native#text/plain
|
tests/test/jvm/tprop.pp svneol=native#text/plain
|
||||||
tests/test/jvm/tprop2.pp svneol=native#text/plain
|
tests/test/jvm/tprop2.pp svneol=native#text/plain
|
||||||
|
@ -36,6 +36,7 @@ type
|
|||||||
protected
|
protected
|
||||||
function is_copyout_addr_param_load: boolean;
|
function is_copyout_addr_param_load: boolean;
|
||||||
function handle_threadvar_access: tnode; override;
|
function handle_threadvar_access: tnode; override;
|
||||||
|
function keep_param_address_in_nested_struct: boolean; override;
|
||||||
public
|
public
|
||||||
function is_addr_param_load: boolean; override;
|
function is_addr_param_load: boolean; override;
|
||||||
procedure pass_generate_code; override;
|
procedure pass_generate_code; override;
|
||||||
@ -189,6 +190,21 @@ function tjvmloadnode.handle_threadvar_access: tnode;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tjvmloadnode.keep_param_address_in_nested_struct: boolean;
|
||||||
|
begin
|
||||||
|
{ we don't need an extra load when implicit pointer types are passed as
|
||||||
|
var/out/constref parameter (since they are already pointers). However,
|
||||||
|
when transfering them into a nestedfp struct, we do want to transfer the
|
||||||
|
pointer and not make a deep copy in case they are var/out/constref (since
|
||||||
|
changes made to the var/out parameter should propagate up) }
|
||||||
|
result:=
|
||||||
|
is_addr_param_load or
|
||||||
|
((symtableentry.typ=paravarsym) and
|
||||||
|
jvmimplicitpointertype(tparavarsym(symtableentry).vardef) and
|
||||||
|
(tparavarsym(symtableentry).varspez in [vs_var,vs_constref,vs_out]));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function tjvmloadnode.is_addr_param_load: boolean;
|
function tjvmloadnode.is_addr_param_load: boolean;
|
||||||
begin
|
begin
|
||||||
result:=
|
result:=
|
||||||
|
@ -40,6 +40,7 @@ interface
|
|||||||
nestsym: tsym;
|
nestsym: tsym;
|
||||||
nestsymderef: tderef;
|
nestsymderef: tderef;
|
||||||
procedure generate_nested_access(vs: tsym);override;
|
procedure generate_nested_access(vs: tsym);override;
|
||||||
|
function keep_param_address_in_nested_struct: boolean; virtual;
|
||||||
public
|
public
|
||||||
function pass_typecheck: tnode; override;
|
function pass_typecheck: tnode; override;
|
||||||
function pass_1:tnode;override;
|
function pass_1:tnode;override;
|
||||||
@ -80,6 +81,12 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tcgnestloadnode.keep_param_address_in_nested_struct: boolean;
|
||||||
|
begin
|
||||||
|
result:=is_addr_param_load;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function tcgnestloadnode.pass_typecheck: tnode;
|
function tcgnestloadnode.pass_typecheck: tnode;
|
||||||
var
|
var
|
||||||
nestedvars: tsym;
|
nestedvars: tsym;
|
||||||
@ -115,7 +122,7 @@ implementation
|
|||||||
nestedvars:=tprocdef(symtable.defowner).parentfpstruct;
|
nestedvars:=tprocdef(symtable.defowner).parentfpstruct;
|
||||||
end;
|
end;
|
||||||
{ store result for use in pass_1 }
|
{ store result for use in pass_1 }
|
||||||
nestsym:=maybe_add_sym_to_parentfpstruct(tprocdef(symtableentry.owner.defowner),symtableentry,resultdef,is_addr_param_load);
|
nestsym:=maybe_add_sym_to_parentfpstruct(tprocdef(symtableentry.owner.defowner),symtableentry,resultdef,keep_param_address_in_nested_struct);
|
||||||
{ left normally holds the parentfp node. If it's not assigned,
|
{ left normally holds the parentfp node. If it's not assigned,
|
||||||
this is an access to a local variable/para from the routine
|
this is an access to a local variable/para from the routine
|
||||||
in which it was actually declared -> redirect to its
|
in which it was actually declared -> redirect to its
|
||||||
|
31
tests/test/jvm/tnestedset.pp
Normal file
31
tests/test/jvm/tnestedset.pp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
program tnestedset;
|
||||||
|
|
||||||
|
{$mode delphi}
|
||||||
|
|
||||||
|
uses
|
||||||
|
jdk15;
|
||||||
|
|
||||||
|
type
|
||||||
|
tnestedfpstructenum = (ea,eb,ec);
|
||||||
|
tnestedfpstructenumset = set of tnestedfpstructenum;
|
||||||
|
|
||||||
|
procedure test(var s: tnestedfpstructenumset);
|
||||||
|
|
||||||
|
procedure sub;
|
||||||
|
begin
|
||||||
|
s:=s+[eb];
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
begin
|
||||||
|
sub
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
s: tnestedfpstructenumset;
|
||||||
|
begin
|
||||||
|
test(s);
|
||||||
|
if s<>[eb] then
|
||||||
|
raise jlexception.create;
|
||||||
|
jlsystem.fout.println(jlstring(juenumset(@s).toString));
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user