* 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:
Jonas Maebe 2011-11-18 21:09:38 +00:00
parent 74510f9069
commit 4dee36b64b
4 changed files with 56 additions and 1 deletions

1
.gitattributes vendored
View File

@ -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

View File

@ -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:=

View File

@ -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

View 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.