Browse Source

* mark the node which is the entry of the user code with a flag
* check for uninitialized variables at the node which is marked as the start of the user code

git-svn-id: trunk@26014 -

florian 11 years ago
parent
commit
3cb747f4a7
3 changed files with 46 additions and 8 deletions
  1. 1 1
      compiler/nbas.pas
  2. 14 6
      compiler/node.pas
  3. 31 1
      compiler/psub.pas

+ 1 - 1
compiler/nbas.pas

@@ -547,7 +547,7 @@ implementation
             result:=tstatementnode(left).left;
             result:=tstatementnode(left).left;
             tstatementnode(left).left:=nil;
             tstatementnode(left).left:=nil;
             { make sure the nf_block_with_exit flag is safeguarded }
             { make sure the nf_block_with_exit flag is safeguarded }
-            result.flags:=result.flags+(flags * [nf_block_with_exit]);
+            result.flags:=result.flags+(flags*[nf_block_with_exit,nf_usercode_entry]);
             exit;
             exit;
           end;
           end;
       end;
       end;

+ 14 - 6
compiler/node.pas

@@ -207,18 +207,26 @@ interface
     type
     type
        { all boolean field of ttree are now collected in flags }
        { all boolean field of ttree are now collected in flags }
        tnodeflag = (
        tnodeflag = (
-         nf_swapable,    { tbinop operands can be swaped }
-         nf_swapped,      { tbinop operands are swaped    }
+         { tbinop operands can be swaped }
+         nf_swapable,
+         { tbinop operands are swaped    }
+         nf_swapped,
          nf_error,
          nf_error,
 
 
          { general }
          { general }
          nf_pass1_done,
          nf_pass1_done,
-         nf_write,       { Node is written to    }
-         nf_modify,      { Node is modified      }
+         { Node is written to    }
+         nf_write,
+         { Node is modified      }
+         nf_modify,
          nf_is_funcret,
          nf_is_funcret,
          nf_isproperty,
          nf_isproperty,
          nf_processing,
          nf_processing,
-         nf_no_lvalue,   { Node cannot be assigned to }
+         { Node cannot be assigned to }
+         nf_no_lvalue,
+         { this node is the user code entry, if a node with this flag is removed
+           during simplify, the flag must be moved to another node }
+         nf_usercode_entry,
 
 
          { taddrnode }
          { taddrnode }
          nf_typedaddr,
          nf_typedaddr,
@@ -268,7 +276,7 @@ interface
          { tloadvmtaddrnode }
          { tloadvmtaddrnode }
          nf_ignore_for_wpo  { we know that this loadvmtaddrnode cannot be used to construct a class instance }
          nf_ignore_for_wpo  { we know that this loadvmtaddrnode cannot be used to construct a class instance }
 
 
-         { WARNING: there are now 31 elements in this type, and a set of this
+         { WARNING: there are now 32 elements in this type, and a set of this
              type is written to the PPU. So before adding more than 32 elements,
              type is written to the PPU. So before adding more than 32 elements,
              either move some flags to specific nodes, or stream a normalset
              either move some flags to specific nodes, or stream a normalset
              to the ppu
              to the ppu

+ 31 - 1
compiler/psub.pas

@@ -37,6 +37,8 @@ interface
       tcgprocinfo = class(tprocinfo)
       tcgprocinfo = class(tprocinfo)
       private
       private
         procedure CreateInlineInfo;
         procedure CreateInlineInfo;
+        { returns the node which is the start of the user code, this is needed by the dfa }
+        function GetUserCode: tnode;
         procedure maybe_add_constructor_wrapper(var tocode: tnode; withexceptblock: boolean);
         procedure maybe_add_constructor_wrapper(var tocode: tnode; withexceptblock: boolean);
         procedure add_entry_exit_code;
         procedure add_entry_exit_code;
         procedure setup_tempgen;
         procedure setup_tempgen;
@@ -1139,6 +1141,30 @@ implementation
        end;
        end;
 
 
 
 
+    function searchusercode(var n: tnode; arg: pointer): foreachnoderesult;
+      begin
+        if nf_usercode_entry in n.flags then
+          begin
+            pnode(arg)^:=n;
+            result:=fen_norecurse_true
+          end
+        else
+          result:=fen_false;
+      end;
+
+
+    function TCGProcinfo.GetUserCode : tnode;
+      var
+        n : tnode;
+      begin
+        n:=nil;
+        foreachnodestatic(code,@searchusercode,@n);
+        if not(assigned(n)) then
+          internalerror(2013111001);
+        result:=n;
+      end;
+
+
     procedure tcgprocinfo.generate_code;
     procedure tcgprocinfo.generate_code;
       var
       var
         old_current_procinfo : tprocinfo;
         old_current_procinfo : tprocinfo;
@@ -1179,6 +1205,10 @@ implementation
         current_filepos:=entrypos;
         current_filepos:=entrypos;
         current_structdef:=procdef.struct;
         current_structdef:=procdef.struct;
 
 
+        { store start of user code, it must be a block node, it will be used later one to
+          check variable lifeness }
+        include(code.flags,nf_usercode_entry);
+
         { add wrapping code if necessary (initialization of typed constants on
         { add wrapping code if necessary (initialization of typed constants on
           some platforms, initing of local variables and out parameters with
           some platforms, initing of local variables and out parameters with
           trashing values, ... }
           trashing values, ... }
@@ -1270,7 +1300,7 @@ implementation
             { iterate through life info of the first node }
             { iterate through life info of the first node }
             for i:=0 to dfabuilder.nodemap.count-1 do
             for i:=0 to dfabuilder.nodemap.count-1 do
               begin
               begin
-                if DFASetIn(code.optinfo^.life,i) then
+                if DFASetIn(GetUserCode.optinfo^.life,i) then
                   case tnode(dfabuilder.nodemap[i]).nodetype of
                   case tnode(dfabuilder.nodemap[i]).nodetype of
                     loadn:
                     loadn:
                       begin
                       begin