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
                      originally declared, except in the initialisation code for
                      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
                   { get struct holding all locals accessed by nested routines }
                   nestedvars:=tprocdef(symtable.defowner).parentfpstruct;
@@ -142,7 +142,6 @@ implementation
       var
         thissym,
         nestedvars: tsym;
-        nestedvarsdef: tdef;
       begin
         result:=inherited;
         if assigned(result) then
@@ -153,11 +152,8 @@ implementation
             begin
               { Nested variable? Then we have to move it to a structure that
                 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
                   { get struct holding all locals accessed by nested routines }
                   nestedvars:=tprocdef(symtable.defowner).parentfpstruct;
@@ -167,7 +163,6 @@ implementation
                       build_parentfpstruct(tprocdef(symtable.defowner));
                       nestedvars:=tprocdef(symtable.defowner).parentfpstruct;
                     end;
-                  nestedvarsdef:=tlocalvarsym(nestedvars).vardef;
                   if nestedvars<>symtableentry then
                     thissym:=nestsym
                   else
@@ -185,7 +180,7 @@ implementation
                   left:=csubscriptnode.create(thissym,cderefnode.create(left));
                   firstpass(left);
                   include(flags,nf_internal);
-                 end;
+                end;
             end;
         end;
       end;

+ 1 - 1
compiler/ninl.pas

@@ -4371,7 +4371,7 @@ implementation
 
          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 }
          node_reset_flags(newstatement.statement,[nf_pass1_done]);
          { firstpass it }