Browse Source

* prevent calling firstpass multiple times for a node (such as when
transforming inc/dec to an addn/subn in case of range checking) from
triggering the transformation logic for accessing nested variables
on LLVM/JVM multiple times
* also prevent it from triggering errors during inlining, in case a
parameter to a nested routine gets replaced by a local variable
from a parent routine (in that case, it does not need to be
accessed via the parentfpstruct, as we are being inlined in the
parent) -> don't duplicate the check from pass_typecheck in pass_1,
but check whether it needs to be accessed via the parentfpstruct
by verifying that tloadnode.left is assigned (which pass_typecheck
will ensure if needed)

git-svn-id: trunk@40630 -

Jonas Maebe 6 years ago
parent
commit
3ccc3e329b
2 changed files with 6 additions and 11 deletions
  1. 5 10
      compiler/ncgnstld.pas
  2. 1 1
      compiler/ninl.pas

+ 5 - 10
compiler/ncgnstld.pas

@@ -106,8 +106,8 @@ implementation
                      the parentfpstruct inside the routine in which they were
                      the parentfpstruct inside the routine in which they were
                      originally declared, except in the initialisation code for
                      originally declared, except in the initialisation code for
                      the parentfpstruct (nf_internal flag) }
                      the parentfpstruct (nf_internal flag) }
-                  (tabstractnormalvarsym(symtableentry).inparentfpstruct and
-                   not(nf_internal in flags))) then
+                  tabstractnormalvarsym(symtableentry).inparentfpstruct) and
+                   not(nf_internal in flags) then
                 begin
                 begin
                   { get struct holding all locals accessed by nested routines }
                   { get struct holding all locals accessed by nested routines }
                   nestedvars:=tprocdef(symtable.defowner).parentfpstruct;
                   nestedvars:=tprocdef(symtable.defowner).parentfpstruct;
@@ -142,7 +142,6 @@ implementation
       var
       var
         thissym,
         thissym,
         nestedvars: tsym;
         nestedvars: tsym;
-        nestedvarsdef: tdef;
       begin
       begin
         result:=inherited;
         result:=inherited;
         if assigned(result) then
         if assigned(result) then
@@ -153,11 +152,8 @@ implementation
             begin
             begin
               { Nested variable? Then we have to move it to a structure that
               { Nested variable? Then we have to move it to a structure that
                 can be passed by reference to nested routines }
                 can be passed by reference to nested routines }
-              if assigned(current_procinfo) and
-                 (symtable.symtabletype in [localsymtable,parasymtable]) and
-                 ((symtable.symtablelevel<>current_procinfo.procdef.parast.symtablelevel) or
-                  (tabstractnormalvarsym(symtableentry).inparentfpstruct and
-                   not(nf_internal in flags))) then
+              if assigned(left) and
+                 not(nf_internal in flags) then
                 begin
                 begin
                   { get struct holding all locals accessed by nested routines }
                   { get struct holding all locals accessed by nested routines }
                   nestedvars:=tprocdef(symtable.defowner).parentfpstruct;
                   nestedvars:=tprocdef(symtable.defowner).parentfpstruct;
@@ -167,7 +163,6 @@ implementation
                       build_parentfpstruct(tprocdef(symtable.defowner));
                       build_parentfpstruct(tprocdef(symtable.defowner));
                       nestedvars:=tprocdef(symtable.defowner).parentfpstruct;
                       nestedvars:=tprocdef(symtable.defowner).parentfpstruct;
                     end;
                     end;
-                  nestedvarsdef:=tlocalvarsym(nestedvars).vardef;
                   if nestedvars<>symtableentry then
                   if nestedvars<>symtableentry then
                     thissym:=nestsym
                     thissym:=nestsym
                   else
                   else
@@ -185,7 +180,7 @@ implementation
                   left:=csubscriptnode.create(thissym,cderefnode.create(left));
                   left:=csubscriptnode.create(thissym,cderefnode.create(left));
                   firstpass(left);
                   firstpass(left);
                   include(flags,nf_internal);
                   include(flags,nf_internal);
-                 end;
+                end;
             end;
             end;
         end;
         end;
       end;
       end;

+ 1 - 1
compiler/ninl.pas

@@ -4371,7 +4371,7 @@ implementation
 
 
          addstatement(newstatement,cassignmentnode.create(resultnode,hpp));
          addstatement(newstatement,cassignmentnode.create(resultnode,hpp));
 
 
-         { force pass 1, so copied tries get first pass'ed as well and flags like nf_write, nf_call_unique
+         { force pass 1, so copied trees get first pass'ed as well and flags like nf_write, nf_call_unique
            get set right }
            get set right }
          node_reset_flags(newstatement.statement,[nf_pass1_done]);
          node_reset_flags(newstatement.statement,[nf_pass1_done]);
          { firstpass it }
          { firstpass it }