Bläddra i källkod

* also in case of constref make_not_regable with ra_addr_taken must be called, later on in pass_1 this happens anyways
* for in loops can generate temp. refs as loop counter, so when checking of the address of the for counter is taken, we have to check for a load node

git-svn-id: trunk@38692 -

florian 7 år sedan
förälder
incheckning
bd27b7635b
2 ändrade filer med 13 tillägg och 10 borttagningar
  1. 6 9
      compiler/ncal.pas
  2. 7 1
      compiler/optloop.pas

+ 6 - 9
compiler/ncal.pas

@@ -1378,15 +1378,12 @@ implementation
                     vs_constref:
                       begin
                         set_varstate(left,vs_readwritten,[vsf_must_be_valid,vsf_use_hints]);
-                        { constref takes also the address, but storing it is actually the compiler
-                          is not supposed to expect }
-                        if parasym.varspez=vs_var then
-                          { compilerprocs never capture the address of their
-                            parameters }
-                          if not(po_compilerproc in aktcallnode.procdefinition.procoptions) then
-                            make_not_regable(left,[ra_addr_regable,ra_addr_taken])
-                          else
-                            make_not_regable(left,[ra_addr_regable])
+                        { compilerprocs never capture the address of their
+                          parameters }
+                        if not(po_compilerproc in aktcallnode.procdefinition.procoptions) then
+                          make_not_regable(left,[ra_addr_regable,ra_addr_taken])
+                        else
+                          make_not_regable(left,[ra_addr_regable])
                       end;
                     else
                       set_varstate(left,vs_read,[vsf_must_be_valid]);

+ 7 - 1
compiler/optloop.pas

@@ -113,7 +113,13 @@ unit optloop;
         if not(node.nodetype in [forn]) then
           exit;
         unrolls:=number_unrolls(tfornode(node).t2);
-        if unrolls>1 then
+        if (unrolls>1) and
+          ((tfornode(node).left.nodetype<>loadn) or
+           { the address of the counter variable might be taken if it is passed by constref to a
+             subroutine, so really check if it is not taken }
+           ((tfornode(node).left.nodetype=loadn) and (tloadnode(tfornode(node).left).symtableentry is tabstractvarsym) and
+            not(tabstractvarsym(tloadnode(tfornode(node).left).symtableentry).addr_taken))
+           ) then
           begin
             { number of executions known? }
             if (tfornode(node).right.nodetype=ordconstn) and (tfornode(node).t1.nodetype=ordconstn) then