mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-02 10:22:33 +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/tint.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/tprop.pp svneol=native#text/plain
|
||||
tests/test/jvm/tprop2.pp svneol=native#text/plain
|
||||
|
@ -36,6 +36,7 @@ type
|
||||
protected
|
||||
function is_copyout_addr_param_load: boolean;
|
||||
function handle_threadvar_access: tnode; override;
|
||||
function keep_param_address_in_nested_struct: boolean; override;
|
||||
public
|
||||
function is_addr_param_load: boolean; override;
|
||||
procedure pass_generate_code; override;
|
||||
@ -189,6 +190,21 @@ function tjvmloadnode.handle_threadvar_access: tnode;
|
||||
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;
|
||||
begin
|
||||
result:=
|
||||
|
@ -40,6 +40,7 @@ interface
|
||||
nestsym: tsym;
|
||||
nestsymderef: tderef;
|
||||
procedure generate_nested_access(vs: tsym);override;
|
||||
function keep_param_address_in_nested_struct: boolean; virtual;
|
||||
public
|
||||
function pass_typecheck: tnode; override;
|
||||
function pass_1:tnode;override;
|
||||
@ -80,6 +81,12 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function tcgnestloadnode.keep_param_address_in_nested_struct: boolean;
|
||||
begin
|
||||
result:=is_addr_param_load;
|
||||
end;
|
||||
|
||||
|
||||
function tcgnestloadnode.pass_typecheck: tnode;
|
||||
var
|
||||
nestedvars: tsym;
|
||||
@ -115,7 +122,7 @@ implementation
|
||||
nestedvars:=tprocdef(symtable.defowner).parentfpstruct;
|
||||
end;
|
||||
{ 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,
|
||||
this is an access to a local variable/para from the routine
|
||||
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