Browse Source

* proper initialised/used warnings for variables used
in complex with-statements + tests

git-svn-id: trunk@6024 -

Jonas Maebe 18 years ago
parent
commit
f2b07704b5
9 changed files with 146 additions and 21 deletions
  1. 3 0
      .gitattributes
  2. 9 1
      compiler/htypechk.pas
  3. 43 6
      compiler/nbas.pas
  4. 26 11
      compiler/nmem.pas
  5. 1 1
      compiler/ppu.pas
  6. 2 2
      compiler/pstatmnt.pas
  7. 21 0
      tests/tbf/tb0196.pp
  8. 21 0
      tests/tbf/tb0197.pp
  9. 20 0
      tests/tbs/tb0525.pp

+ 3 - 0
.gitattributes

@@ -5665,6 +5665,8 @@ tests/tbf/tb0192.pp svneol=native#text/plain
 tests/tbf/tb0193.pp svneol=native#text/plain
 tests/tbf/tb0193.pp svneol=native#text/plain
 tests/tbf/tb0194.pp svneol=native#text/plain
 tests/tbf/tb0194.pp svneol=native#text/plain
 tests/tbf/tb0195.pp svneol=native#text/plain
 tests/tbf/tb0195.pp svneol=native#text/plain
+tests/tbf/tb0196.pp svneol=native#text/plain
+tests/tbf/tb0197.pp svneol=native#text/plain
 tests/tbf/ub0115.pp svneol=native#text/plain
 tests/tbf/ub0115.pp svneol=native#text/plain
 tests/tbf/ub0149.pp svneol=native#text/plain
 tests/tbf/ub0149.pp svneol=native#text/plain
 tests/tbf/ub0158a.pp svneol=native#text/plain
 tests/tbf/ub0158a.pp svneol=native#text/plain
@@ -6186,6 +6188,7 @@ tests/tbs/tb0521.pp svneol=native#text/plain
 tests/tbs/tb0522.pp svneol=native#text/plain
 tests/tbs/tb0522.pp svneol=native#text/plain
 tests/tbs/tb0523.pp svneol=native#text/plain
 tests/tbs/tb0523.pp svneol=native#text/plain
 tests/tbs/tb0524.pp svneol=native#text/x-pascal
 tests/tbs/tb0524.pp svneol=native#text/x-pascal
+tests/tbs/tb0525.pp svneol=native#text/plain
 tests/tbs/ub0060.pp svneol=native#text/plain
 tests/tbs/ub0060.pp svneol=native#text/plain
 tests/tbs/ub0069.pp svneol=native#text/plain
 tests/tbs/ub0069.pp svneol=native#text/plain
 tests/tbs/ub0119.pp svneol=native#text/plain
 tests/tbs/ub0119.pp svneol=native#text/plain

+ 9 - 1
compiler/htypechk.pas

@@ -775,7 +775,7 @@ implementation
           { vs_read_not_warned -> ... }
           { vs_read_not_warned -> ... }
           (vs_none,vs_read_not_warned,vs_read,vs_read,vs_read_not_warned,vs_read_not_warned,vs_readwritten,vs_readwritten),
           (vs_none,vs_read_not_warned,vs_read,vs_read,vs_read_not_warned,vs_read_not_warned,vs_readwritten,vs_readwritten),
           { vs_referred_not_inited }
           { vs_referred_not_inited }
-          (vs_none,vs_referred_not_inited,vs_read,vs_read,vs_read,vs_referred_not_inited,vs_readwritten,vs_readwritten),
+          (vs_none,vs_referred_not_inited,vs_read,vs_read,vs_read_not_warned,vs_referred_not_inited,vs_written,vs_readwritten),
           { vs_written -> ... }
           { vs_written -> ... }
           (vs_none,vs_written,vs_written,vs_readwritten,vs_readwritten,vs_written,vs_written,vs_readwritten),
           (vs_none,vs_written,vs_written,vs_readwritten,vs_readwritten,vs_written,vs_written,vs_readwritten),
           { vs_readwritten -> ... }
           { vs_readwritten -> ... }
@@ -791,6 +791,14 @@ implementation
         while assigned(p) do
         while assigned(p) do
          begin
          begin
            case p.nodetype of
            case p.nodetype of
+             derefn:
+               begin
+                 if (tderefnode(p).left.nodetype=temprefn) and
+                    assigned(ttemprefnode(tderefnode(p).left).tempinfo^.withnode) then
+                   p:=ttemprefnode(tderefnode(p).left).tempinfo^.withnode
+                 else
+                   break;
+               end;
              typeconvn :
              typeconvn :
                begin
                begin
                  case ttypeconvnode(p).convtype of
                  case ttypeconvnode(p).convtype of

+ 43 - 6
compiler/nbas.pas

@@ -104,10 +104,11 @@ interface
          typedefderef               : tderef;
          typedefderef               : tderef;
          temptype                   : ttemptype;
          temptype                   : ttemptype;
          owner                      : ttempcreatenode;
          owner                      : ttempcreatenode;
+         withnode                   : tnode;
+         location                   : tlocation;
          may_be_in_reg              : boolean;
          may_be_in_reg              : boolean;
          valid                      : boolean;
          valid                      : boolean;
          nextref_set_hookoncopy_nil : boolean;
          nextref_set_hookoncopy_nil : boolean;
-         location                   : tlocation;
        end;
        end;
 
 
        { a node which will create a (non)persistent temp of a given type with a given  }
        { a node which will create a (non)persistent temp of a given type with a given  }
@@ -123,10 +124,12 @@ interface
           { freeing it. In this last case, you must use only one reference      }
           { freeing it. In this last case, you must use only one reference      }
           { to it and *not* generate a ttempdeletenode                          }
           { to it and *not* generate a ttempdeletenode                          }
           constructor create(_typedef: tdef; _size: aint; _temptype: ttemptype;allowreg:boolean); virtual;
           constructor create(_typedef: tdef; _size: aint; _temptype: ttemptype;allowreg:boolean); virtual;
+          constructor create_withnode(_typedef: tdef; _size: aint; _temptype: ttemptype; allowreg:boolean; withnode: tnode); virtual;
           constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
           constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure buildderefimpl;override;
           procedure buildderefimpl;override;
           procedure derefimpl;override;
           procedure derefimpl;override;
+          procedure derefnode;override;
           function dogetcopy: tnode; override;
           function dogetcopy: tnode; override;
           function pass_1 : tnode; override;
           function pass_1 : tnode; override;
           function pass_typecheck: tnode; override;
           function pass_typecheck: tnode; override;
@@ -632,7 +635,8 @@ implementation
         fillchar(tempinfo^,sizeof(tempinfo^),0);
         fillchar(tempinfo^,sizeof(tempinfo^),0);
         tempinfo^.typedef := _typedef;
         tempinfo^.typedef := _typedef;
         tempinfo^.temptype := _temptype;
         tempinfo^.temptype := _temptype;
-        tempinfo^.owner:=self;
+        tempinfo^.owner := self;
+        tempinfo^.withnode := nil;
         tempinfo^.may_be_in_reg:=
         tempinfo^.may_be_in_reg:=
           allowreg and
           allowreg and
           { temp must fit a single register }
           { temp must fit a single register }
@@ -647,6 +651,13 @@ implementation
            (not tpointerdef(_typedef).pointeddef.needs_inittable));
            (not tpointerdef(_typedef).pointeddef.needs_inittable));
       end;
       end;
 
 
+    constructor ttempcreatenode.create_withnode(_typedef: tdef; _size: aint; _temptype: ttemptype; allowreg:boolean; withnode: tnode);
+      begin
+        self.create(_typedef,_size,_temptype,allowreg);
+        tempinfo^.withnode:=withnode.getcopy;
+      end;
+
+
     function ttempcreatenode.dogetcopy: tnode;
     function ttempcreatenode.dogetcopy: tnode;
       var
       var
         n: ttempcreatenode;
         n: ttempcreatenode;
@@ -659,6 +670,10 @@ implementation
         n.tempinfo^.owner:=n;
         n.tempinfo^.owner:=n;
         n.tempinfo^.typedef := tempinfo^.typedef;
         n.tempinfo^.typedef := tempinfo^.typedef;
         n.tempinfo^.temptype := tempinfo^.temptype;
         n.tempinfo^.temptype := tempinfo^.temptype;
+        if assigned(tempinfo^.withnode) then
+          n.tempinfo^.withnode := tempinfo^.withnode.getcopy
+        else
+          n.tempinfo^.withnode := nil;
 
 
         { when the tempinfo has already a hookoncopy then it is not
         { when the tempinfo has already a hookoncopy then it is not
           reset by a tempdeletenode }
           reset by a tempdeletenode }
@@ -686,6 +701,7 @@ implementation
         ppufile.getderef(tempinfo^.typedefderef);
         ppufile.getderef(tempinfo^.typedefderef);
         tempinfo^.temptype := ttemptype(ppufile.getbyte);
         tempinfo^.temptype := ttemptype(ppufile.getbyte);
         tempinfo^.owner:=self;
         tempinfo^.owner:=self;
+        tempinfo^.withnode:=ppuloadnode(ppufile);
       end;
       end;
 
 
 
 
@@ -696,27 +712,44 @@ implementation
         ppufile.putbyte(byte(tempinfo^.may_be_in_reg));
         ppufile.putbyte(byte(tempinfo^.may_be_in_reg));
         ppufile.putderef(tempinfo^.typedefderef);
         ppufile.putderef(tempinfo^.typedefderef);
         ppufile.putbyte(byte(tempinfo^.temptype));
         ppufile.putbyte(byte(tempinfo^.temptype));
+        ppuwritenode(ppufile,tempinfo^.withnode);
       end;
       end;
 
 
 
 
     procedure ttempcreatenode.buildderefimpl;
     procedure ttempcreatenode.buildderefimpl;
       begin
       begin
+        inherited buildderefimpl;
         tempinfo^.typedefderef.build(tempinfo^.typedef);
         tempinfo^.typedefderef.build(tempinfo^.typedef);
+        if assigned(tempinfo^.withnode) then
+          tempinfo^.withnode.buildderefimpl;
       end;
       end;
 
 
 
 
     procedure ttempcreatenode.derefimpl;
     procedure ttempcreatenode.derefimpl;
       begin
       begin
+        inherited derefimpl;
         tempinfo^.typedef:=tdef(tempinfo^.typedefderef.resolve);
         tempinfo^.typedef:=tdef(tempinfo^.typedefderef.resolve);
+        if assigned(tempinfo^.withnode) then
+          tempinfo^.withnode.derefimpl;
+      end;
+
+
+    procedure ttempcreatenode.derefnode;
+      begin
+        inherited derefnode;
+        if assigned(tempinfo^.withnode) then
+          tempinfo^.withnode.derefnode;
       end;
       end;
 
 
 
 
     function ttempcreatenode.pass_1 : tnode;
     function ttempcreatenode.pass_1 : tnode;
       begin
       begin
-         result := nil;
-         expectloc:=LOC_VOID;
-         if (tempinfo^.typedef.needs_inittable) then
-           include(current_procinfo.flags,pi_needs_implicit_finally);
+        result := nil;
+        expectloc:=LOC_VOID;
+        if (tempinfo^.typedef.needs_inittable) then
+          include(current_procinfo.flags,pi_needs_implicit_finally);
+        if assigned(tempinfo^.withnode) then
+          firstpass(tempinfo^.withnode);
       end;
       end;
 
 
 
 
@@ -725,6 +758,8 @@ implementation
         result := nil;
         result := nil;
         { a tempcreatenode doesn't have a resultdef, only temprefnodes do }
         { a tempcreatenode doesn't have a resultdef, only temprefnodes do }
         resultdef := voidtype;
         resultdef := voidtype;
+        if assigned(tempinfo^.withnode) then
+          typecheckpass(tempinfo^.withnode);
       end;
       end;
 
 
 
 
@@ -734,6 +769,7 @@ implementation
           inherited docompare(p) and
           inherited docompare(p) and
           (ttempcreatenode(p).size = size) and
           (ttempcreatenode(p).size = size) and
           (ttempcreatenode(p).tempinfo^.may_be_in_reg = tempinfo^.may_be_in_reg) and
           (ttempcreatenode(p).tempinfo^.may_be_in_reg = tempinfo^.may_be_in_reg) and
+          (ttempcreatenode(p).tempinfo^.withnode.isequal(tempinfo^.withnode)) and
           equal_defs(ttempcreatenode(p).tempinfo^.typedef,tempinfo^.typedef);
           equal_defs(ttempcreatenode(p).tempinfo^.typedef,tempinfo^.typedef);
       end;
       end;
 
 
@@ -818,6 +854,7 @@ implementation
       var
       var
         temp : ttempcreatenode;
         temp : ttempcreatenode;
       begin
       begin
+        inherited derefnode;
         temp:=ttempcreatenode(nodeppuidxget(tempidx));
         temp:=ttempcreatenode(nodeppuidxget(tempidx));
         if temp.nodetype<>tempcreaten then
         if temp.nodetype<>tempcreaten then
           internalerror(200311075);
           internalerror(200311075);

+ 26 - 11
compiler/nmem.pas

@@ -56,6 +56,7 @@ interface
           getprocvardefderef : tderef;
           getprocvardefderef : tderef;
           constructor create(l : tnode);virtual;
           constructor create(l : tnode);virtual;
           constructor create_internal(l : tnode); virtual;
           constructor create_internal(l : tnode); virtual;
+          constructor create_internal_nomark(l : tnode); virtual;
           constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
           constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure mark_write;override;
           procedure mark_write;override;
@@ -64,6 +65,8 @@ interface
           function dogetcopy : tnode;override;
           function dogetcopy : tnode;override;
           function pass_1 : tnode;override;
           function pass_1 : tnode;override;
           function pass_typecheck:tnode;override;
           function pass_typecheck:tnode;override;
+         private
+          mark_read_written: boolean;
        end;
        end;
        taddrnodeclass = class of taddrnode;
        taddrnodeclass = class of taddrnode;
 
 
@@ -275,6 +278,7 @@ implementation
       begin
       begin
          inherited create(addrn,l);
          inherited create(addrn,l);
          getprocvardef:=nil;
          getprocvardef:=nil;
+         mark_read_written := true;
       end;
       end;
 
 
 
 
@@ -285,6 +289,13 @@ implementation
       end;
       end;
 
 
 
 
+    constructor taddrnode.create_internal_nomark(l : tnode);
+      begin
+        self.create_internal(l);
+        mark_read_written := false;
+      end;
+
+
     constructor taddrnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
     constructor taddrnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
       begin
       begin
         inherited ppuload(t,ppufile);
         inherited ppuload(t,ppufile);
@@ -445,17 +456,21 @@ implementation
               CGMessage(type_e_variable_id_expected);
               CGMessage(type_e_variable_id_expected);
           end;
           end;
 
 
-         { this is like the function addr }
-         inc(parsing_para_level);
-         { This is actually only "read", but treat it nevertheless as  }
-         { modified due to the possible use of pointers                }
-         { To avoid false positives regarding "uninitialised"          }
-         { warnings when using arrays, perform it in two steps         }
-         set_varstate(left,vs_written,[]);
-         { vsf_must_be_valid so it doesn't get changed into }
-         { vsf_referred_not_inited                          }
-         set_varstate(left,vs_read,[vsf_must_be_valid]);
-         dec(parsing_para_level);
+        if (mark_read_written) then
+          begin
+            { this is like the function addr }
+            inc(parsing_para_level);
+
+            { This is actually only "read", but treat it nevertheless as  }
+            { modified due to the possible use of pointers                }
+            { To avoid false positives regarding "uninitialised"          }
+            { warnings when using arrays, perform it in two steps         }
+            set_varstate(left,vs_written,[]);
+            { vsf_must_be_valid so it doesn't get changed into }
+            { vsf_referred_not_inited                          }
+            set_varstate(left,vs_read,[vsf_must_be_valid]);
+            dec(parsing_para_level);
+          end;
       end;
       end;
 
 
 
 

+ 1 - 1
compiler/ppu.pas

@@ -43,7 +43,7 @@ type
 {$endif Test_Double_checksum}
 {$endif Test_Double_checksum}
 
 
 const
 const
-  CurrentPPUVersion=73;
+  CurrentPPUVersion=74;
 
 
 { buffer sizes }
 { buffer sizes }
   maxentrysize = 1024;
   maxentrysize = 1024;

+ 2 - 2
compiler/pstatmnt.pas

@@ -526,7 +526,7 @@ implementation
                 else
                 else
                   hdef:=tpointerdef.create(p.resultdef);
                   hdef:=tpointerdef.create(p.resultdef);
                 { load address of the value in a temp }
                 { load address of the value in a temp }
-                tempnode:=ctempcreatenode.create(hdef,sizeof(aint),tt_persistent,true);
+                tempnode:=ctempcreatenode.create_withnode(hdef,sizeof(aint),tt_persistent,true,p);
                 typecheckpass(tempnode);
                 typecheckpass(tempnode);
                 valuenode:=p;
                 valuenode:=p;
                 refnode:=ctemprefnode.create(tempnode);
                 refnode:=ctemprefnode.create(tempnode);
@@ -535,7 +535,7 @@ implementation
                   is not done implicitly }
                   is not done implicitly }
                 if not hasimplicitderef then
                 if not hasimplicitderef then
                   begin
                   begin
-                    valuenode:=caddrnode.create_internal(valuenode);
+                    valuenode:=caddrnode.create_internal_nomark(valuenode);
                     refnode:=cderefnode.create(refnode);
                     refnode:=cderefnode.create(refnode);
                     fillchar(refnode.fileinfo,sizeof(tfileposinfo),0);
                     fillchar(refnode.fileinfo,sizeof(tfileposinfo),0);
                   end;
                   end;

+ 21 - 0
tests/tbf/tb0196.pp

@@ -0,0 +1,21 @@
+{ %norun }
+{ %fail }
+{ %opt=-Sen }
+
+type
+ tr = record
+   x, y: longint;
+ end;
+ ta = array[1..10] of tr;
+
+var
+  a: ta;
+  i: longint;
+begin
+  for i := low(a) to high(a) do
+    with a[i] do
+      begin
+        x:=i*2;
+        y:=i+5;
+      end;
+end.

+ 21 - 0
tests/tbf/tb0197.pp

@@ -0,0 +1,21 @@
+{ %norun }
+{ %fail }
+{ %opt=-Sew }
+
+type
+ tr = record
+   x, y: longint;
+ end;
+ ta = array[1..10] of tr;
+
+var
+  a: ta;
+  i: longint;
+begin
+  for i := low(a) to high(a) do
+    with a[i] do
+      begin
+        x:=i*2+y;
+        y:=i+5;
+      end;
+end.

+ 20 - 0
tests/tbs/tb0525.pp

@@ -0,0 +1,20 @@
+{ %norun }
+{ %opt=-Sen }
+
+type
+ tr = record
+   x, y: longint;
+ end;
+ ta = array[1..10] of tr;
+
+var
+  a: ta;
+  i: longint;
+begin
+  for i := low(a) to high(a) do
+    with a[i] do
+      begin
+        x:=i*2;
+        y:=i+5+x;
+      end;
+end.