Browse Source

* new categories for vs_*: vs_declared, vs_initialised, vs_read,
vs_written, vs_readwritten. vs_initialised is the old vs_assigned;
vs_used has been replaced by vs_read, vs_written and vs_readwritten
* the valid_for_*() routines in htypechk now get an extra parameter to
decide whether or not errors should be reported

git-svn-id: trunk@1913 -

Jonas Maebe 19 years ago
parent
commit
42ec76598c

+ 5 - 5
compiler/alpha/radirect.pas

@@ -80,7 +80,7 @@ interface
             { consider it set function set if the offset was loaded }
            if assigned(aktprocdef.funcretsym) and
               (pos(retstr,upper(s))>0) then
-             tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_assigned;
+             tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_initialised;
            s:='';
          end;
 
@@ -89,7 +89,7 @@ interface
        s:='';
        if assigned(aktprocdef.funcretsym) and
           is_fpu(aktprocdef.rettype.def) then
-         tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_assigned;
+         tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_initialised;
        { !!!!!
        if (not is_void(aktprocdef.rettype.def)) then
          retstr:=upper(tostr(procinfo^.return_offset)+'('+gas_reg2str[procinfo^.framepointer]+')')
@@ -149,7 +149,7 @@ interface
                                    ret_in_acc(aktprocdef.rettype.def) and
                                    ((pos('AX',upper(hs))>0) or
                                    (pos('AL',upper(hs))>0)) then
-                                  tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_assigned;
+                                  tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_initialised;
                                 }
                                 if ((s[length(s)]<>'0') or (hs[1]<>'x')) then
                                   begin
@@ -197,7 +197,7 @@ interface
                                                     inc(l,aktprocdef.parast.address_fixup);
                                                     hs:=tostr(l)+'('+gas_reg2str[procinfo.framepointer]+')';
                                                     if pos(',',s) > 0 then
-                                                      tvarsym(sym).varstate:=vs_used;
+                                                      tvarsym(sym).varstate:=vs_readwritten;
                                                  end;
                                             end
                                           { I added that but it creates a problem in line.ppi
@@ -277,7 +277,7 @@ interface
               '{',';',#10,#13:
                 begin
                    if pos(retstr,s) > 0 then
-                     tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_assigned;
+                     tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_initialised;
                    writeasmline;
                    c:=current_scanner.asmgetchar;
                 end;

+ 80 - 41
compiler/htypechk.pas

@@ -141,11 +141,11 @@ interface
     { takes care of type casts etc.                 }
     procedure set_unique(p : tnode);
 
-    function  valid_for_formal_var(p : tnode) : boolean;
-    function  valid_for_formal_const(p : tnode) : boolean;
-    function  valid_for_var(p:tnode):boolean;
-    function  valid_for_assignment(p:tnode):boolean;
-    function  valid_for_addr(p : tnode) : boolean;
+    function  valid_for_formal_var(p : tnode; report_errors: boolean) : boolean;
+    function  valid_for_formal_const(p : tnode; report_errors: boolean) : boolean;
+    function  valid_for_var(p:tnode; report_errors: boolean):boolean;
+    function  valid_for_assignment(p:tnode; report_errors: boolean):boolean;
+    function  valid_for_addr(p : tnode; report_errors: boolean) : boolean;
 
     function allowenumop(nt:tnodetype):boolean;
 
@@ -735,6 +735,20 @@ implementation
 
 
     procedure set_varstate(p:tnode;newstate:tvarstate;varstateflags:tvarstateflags);
+      const
+        vstrans: array[tvarstate,tvarstate] of tvarstate = (
+          { vs_none -> ... }
+          (vs_none,vs_declared,vs_initialised,vs_read,vs_written,vs_readwritten),
+          { vs_declared -> ... }
+          (vs_none,vs_declared,vs_initialised,vs_read,vs_written,vs_readwritten),
+          { vs_initialised -> ... }
+          (vs_none,vs_initialised,vs_initialised,vs_read,vs_written,vs_readwritten),
+          { vs_read -> ... }
+          (vs_none,vs_read,vs_read,vs_read,vs_readwritten,vs_readwritten),
+          { vs_written -> ... }
+          (vs_none,vs_written,vs_written,vs_readwritten,vs_written,vs_readwritten),
+          { vs_readwritten -> ... }
+          (vs_none,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten));
       var
         hsym : tabstractvarsym;
       begin
@@ -758,7 +772,7 @@ implementation
                p:=tunarynode(p).left;
              vecn:
                begin
-                 set_varstate(tbinarynode(p).right,vs_used,[vsf_must_be_valid]);
+                 set_varstate(tbinarynode(p).right,vs_readwritten,[vsf_must_be_valid]);
                  if not(tunarynode(p).left.resulttype.def.deftype in [stringdef,arraydef]) then
                    include(varstateflags,vsf_must_be_valid);
                  p:=tunarynode(p).left;
@@ -801,9 +815,8 @@ implementation
                               end;
                           end;
                       end;
-                    { don't override vs_used with vs_assigned }
-                    if hsym.varstate<>vs_used then
-                      hsym.varstate:=newstate;
+                    { don't override vs_readwritten with vs_initialised }
+                    hsym.varstate := vstrans[hsym.varstate,newstate];
                   end;
                  break;
                end;
@@ -837,7 +850,7 @@ implementation
       end;
 
 
-    function  valid_for_assign(p:tnode;opts:TValidAssigns):boolean;
+    function  valid_for_assign(p:tnode;opts:TValidAssigns; report_errors: boolean):boolean;
       var
         hp : tnode;
         gotstring,
@@ -871,7 +884,8 @@ implementation
         if not(valid_void in opts) and
            is_void(hp.resulttype.def) then
          begin
-           CGMessagePos(hp.fileinfo,errmsg);
+           if report_errors then
+             CGMessagePos(hp.fileinfo,errmsg);
            exit;
          end;
         while assigned(hp) do
@@ -906,7 +920,8 @@ implementation
                             ) then
                         result:=true
                       else
-                        CGMessagePos(hp.fileinfo,errmsg);
+                        if report_errors then
+                          CGMessagePos(hp.fileinfo,errmsg);
                     end
                   else
                     begin
@@ -928,7 +943,8 @@ implementation
                          ) then
                         result:=true
                       else
-                        CGMessagePos(hp.fileinfo,errmsg);
+                        if report_errors then
+                          CGMessagePos(hp.fileinfo,errmsg);
                     end;
                 end
               else
@@ -977,13 +993,15 @@ implementation
                        (todef.size<fromdef.size) then
                       make_not_regable(hp)
                     else
-                      CGMessagePos2(hp.fileinfo,type_e_typecast_wrong_size_for_assignment,tostr(fromdef.size),tostr(todef.size));
+                      if report_errors then
+                        CGMessagePos2(hp.fileinfo,type_e_typecast_wrong_size_for_assignment,tostr(fromdef.size),tostr(todef.size));
                   end;
                  { don't allow assignments to typeconvs that need special code }
                  if not(gotsubscript or gotvec or gotderef) and
                     not(ttypeconvnode(hp).assign_allowed) then
                    begin
-                     CGMessagePos(hp.fileinfo,errmsg);
+                     if report_errors then
+                       CGMessagePos(hp.fileinfo,errmsg);
                      exit;
                    end;
                  case hp.resulttype.def.deftype of
@@ -1017,7 +1035,8 @@ implementation
                    of reference. }
                  if not(gotsubscript or gotderef or gotvec) then
                    begin
-                     CGMessagePos(hp.fileinfo,errmsg);
+                     if report_errors then
+                       CGMessagePos(hp.fileinfo,errmsg);
                      exit;
                    end;
                  hp:=tunarynode(hp).left;
@@ -1028,7 +1047,12 @@ implementation
                  { loop counter? }
                  if not(Valid_Const in opts) and
                     (vo_is_loop_counter in tsubscriptnode(hp).vs.varoptions) then
-                   CGMessage1(parser_e_illegal_assignment_to_count_var,tsubscriptnode(hp).vs.realname);
+                   begin
+                     if report_errors then
+                       CGMessage1(parser_e_illegal_assignment_to_count_var,tsubscriptnode(hp).vs.realname)
+                     else
+                       exit;
+                   end;                     
                  { a class/interface access is an implicit }
                  { dereferencing                           }
                  hp:=tsubscriptnode(hp).left;
@@ -1059,7 +1083,8 @@ implementation
                       (hp.resulttype.def.deftype=stringdef) then
                      result:=true
                  else
-                  CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
+                  if report_errors then
+                   CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
                  exit;
                end;
              niln,
@@ -1069,7 +1094,8 @@ implementation
                  if gotderef then
                   result:=true
                  else
-                  CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
+                  if report_errors then
+                   CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
                  exit;
                end;
              addrn :
@@ -1077,7 +1103,8 @@ implementation
                  if gotderef then
                   result:=true
                  else
-                  CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
+                  if report_errors then
+                   CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
                  exit;
                end;
              calln :
@@ -1123,7 +1150,8 @@ implementation
                    if ([valid_const,valid_addr] * opts = [valid_const]) then
                      result:=true
                  else
-                  CGMessagePos(hp.fileinfo,errmsg);
+                  if report_errors then
+                   CGMessagePos(hp.fileinfo,errmsg);
                  exit;
                end;
              inlinen :
@@ -1132,7 +1160,8 @@ implementation
                     (tinlinenode(hp).inlinenumber in [in_typeof_x]) then
                    result:=true
                  else
-                   CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
+                   if report_errors then
+                    CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
                  exit;
                end;
              loadn :
@@ -1147,7 +1176,10 @@ implementation
                        if not(Valid_Const in opts) and
                           not gotderef and
                           (vo_is_loop_counter in tabstractvarsym(tloadnode(hp).symtableentry).varoptions) then
-                         CGMessage1(parser_e_illegal_assignment_to_count_var,tloadnode(hp).symtableentry.realname);
+                         if report_errors then
+                          CGMessage1(parser_e_illegal_assignment_to_count_var,tloadnode(hp).symtableentry.realname)
+                         else
+                          exit;
                        { derefed pointer }
                        if (tabstractvarsym(tloadnode(hp).symtableentry).varspez=vs_const) then
                         begin
@@ -1155,7 +1187,8 @@ implementation
                           if gotderef or gotdynarray or (Valid_Const in opts) then
                            result:=true
                           else
-                           CGMessagePos(tloadnode(hp).fileinfo,type_e_no_assign_to_const);
+                           if report_errors then
+                            CGMessagePos(tloadnode(hp).fileinfo,type_e_no_assign_to_const);
                           exit;
                         end;
                        { Are we at a with symtable, then we need to process the
@@ -1179,7 +1212,8 @@ implementation
                           (valid_const in opts) then
                         result:=true
                        else
-                        CGMessagePos(hp.fileinfo,type_e_no_assign_to_const);
+                        if report_errors then
+                         CGMessagePos(hp.fileinfo,type_e_no_assign_to_const);
                        exit;
                      end;
                    procsym :
@@ -1187,7 +1221,8 @@ implementation
                        if (Valid_Const in opts) then
                          result:=true
                        else
-                         CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
+                         if report_errors then
+                          CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
                        exit;
                      end;
                    labelsym :
@@ -1195,7 +1230,8 @@ implementation
                        if (Valid_Addr in opts) then
                          result:=true
                        else
-                         CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
+                         if report_errors then
+                          CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
                        exit;
                      end;
                    constsym:
@@ -1204,19 +1240,22 @@ implementation
                          (valid_addr in opts) then
                          result:=true
                        else
-                         CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
+                         if report_errors then
+                          CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
                        exit;
                      end;
                    else
                      begin
-                       CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
+                       if report_errors then
+                        CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
                        exit;
                      end;
                  end;
                end;
              else
                begin
-                 CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
+                 if report_errors then
+                  CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
                  exit;
                end;
             end;
@@ -1224,34 +1263,34 @@ implementation
       end;
 
 
-    function  valid_for_var(p:tnode):boolean;
+    function  valid_for_var(p:tnode; report_errors: boolean):boolean;
       begin
-        valid_for_var:=valid_for_assign(p,[]);
+        valid_for_var:=valid_for_assign(p,[],report_errors);
       end;
 
 
-    function  valid_for_formal_var(p : tnode) : boolean;
+    function  valid_for_formal_var(p : tnode; report_errors: boolean) : boolean;
       begin
-        valid_for_formal_var:=valid_for_assign(p,[valid_void]);
+        valid_for_formal_var:=valid_for_assign(p,[valid_void],report_errors);
       end;
 
 
-    function  valid_for_formal_const(p : tnode) : boolean;
+    function  valid_for_formal_const(p : tnode; report_errors: boolean) : boolean;
       begin
         valid_for_formal_const:=(p.resulttype.def.deftype=formaldef) or
-          valid_for_assign(p,[valid_void,valid_const]);
+          valid_for_assign(p,[valid_void,valid_const],report_errors);
       end;
 
 
-    function  valid_for_assignment(p:tnode):boolean;
+    function  valid_for_assignment(p:tnode; report_errors: boolean):boolean;
       begin
-        valid_for_assignment:=valid_for_assign(p,[valid_property]);
+        valid_for_assignment:=valid_for_assign(p,[valid_property],report_errors);
       end;
 
 
-    function  valid_for_addr(p : tnode) : boolean;
+    function  valid_for_addr(p : tnode; report_errors: boolean) : boolean;
       begin
-        result:=valid_for_assign(p,[valid_const,valid_addr,valid_void]);
+        result:=valid_for_assign(p,[valid_const,valid_addr,valid_void],report_errors);
       end;
 
 
@@ -2134,7 +2173,7 @@ implementation
           begin
             { Maybe passing the correct type but passing a const to var parameter }
             if (compare_defs(pt.resulttype.def,wrongpara.vartype.def,pt.nodetype)<>te_incompatible) and
-               not valid_for_var(pt.left) then
+               not valid_for_var(pt.left,true) then
               CGMessagePos(pt.left.fileinfo,type_e_variable_id_expected)
             else
               CGMessagePos2(pt.left.fileinfo,parser_e_call_by_ref_without_typeconv,

+ 2 - 2
compiler/nadd.pas

@@ -678,8 +678,8 @@ implementation
          resulttypepass(left);
          resulttypepass(right);
          { both left and right need to be valid }
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
-         set_varstate(right,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
+         set_varstate(right,vs_read,[vsf_must_be_valid]);
          if codegenerror then
            exit;
 

+ 13 - 12
compiler/ncal.pas

@@ -550,7 +550,7 @@ type
                    floatdef :
                      inserttypeconv(left,s64floattype);
                  end;
-                 set_varstate(left,vs_used,[vsf_must_be_valid]);
+                 set_varstate(left,vs_read,[vsf_must_be_valid]);
                  resulttype:=left.resulttype;
                  { also update parasym type to get the correct parameter location
                    for the new types }
@@ -559,7 +559,7 @@ type
              else
               if (vo_is_hidden_para in parasym.varoptions) then
                begin
-                 set_varstate(left,vs_used,[vsf_must_be_valid]);
+                 set_varstate(left,vs_read,[vsf_must_be_valid]);
                  resulttype:=left.resulttype;
                end
              else
@@ -660,12 +660,12 @@ type
                        vs_var,
                        vs_out :
                          begin
-                           if not valid_for_formal_var(left) then
+                           if not valid_for_formal_var(left,true) then
                             CGMessagePos(left.fileinfo,parser_e_illegal_parameter_list);
                          end;
                        vs_const :
                          begin
-                           if not valid_for_formal_const(left) then
+                           if not valid_for_formal_const(left,true) then
                             CGMessagePos(left.fileinfo,parser_e_illegal_parameter_list);
                          end;
                      end;
@@ -674,7 +674,7 @@ type
                    begin
                      { check if the argument is allowed }
                      if (parasym.varspez in [vs_out,vs_var]) then
-                       valid_for_var(left);
+                       valid_for_var(left,true);
                    end;
 
                  if parasym.varspez = vs_var then
@@ -701,11 +701,11 @@ type
                   begin
                     case parasym.varspez of
                       vs_out :
-                        set_varstate(left,vs_used,[]);
+                        set_varstate(left,vs_written,[]);
                       vs_var :
-                        set_varstate(left,vs_used,[vsf_must_be_valid,vsf_use_hints]);
+                        set_varstate(left,vs_readwritten,[vsf_must_be_valid,vsf_use_hints]);
                       else
-                        set_varstate(left,vs_used,[vsf_must_be_valid]);
+                        set_varstate(left,vs_read,[vsf_must_be_valid]);
                     end;
                   end;
                  { must only be done after typeconv PM }
@@ -1569,7 +1569,7 @@ type
          { procedure variable ? }
          if assigned(right) then
            begin
-              set_varstate(right,vs_used,[vsf_must_be_valid]);
+              set_varstate(right,vs_read,[vsf_must_be_valid]);
               resulttypepass(right);
               if codegenerror then
                exit;
@@ -1877,14 +1877,15 @@ type
                     )
                    )
                   ) then
-                 set_varstate(methodpointer,vs_used,[])
+                 set_varstate(methodpointer,vs_read,[])
                else
-                 set_varstate(methodpointer,vs_used,[vsf_must_be_valid]);
+                 set_varstate(methodpointer,vs_read,[vsf_must_be_valid]);
 
                { The object is already used if it is called once }
                if (hpt.nodetype=loadn) and
                   (tloadnode(hpt).symtableentry.typ in [localvarsym,paravarsym,globalvarsym]) then
-                 tabstractvarsym(tloadnode(hpt).symtableentry).varstate:=vs_used;
+                 set_varstate(hpt,vs_read,[]);
+//                 tabstractvarsym(tloadnode(hpt).symtableentry).varstate:=vs_readwritten;
              end;
 
             { if we are calling the constructor check for abstract

+ 6 - 6
compiler/ncnv.pas

@@ -371,11 +371,11 @@ implementation
                  p3:=nil;
                end;
               resulttypepass(p2);
-              set_varstate(p2,vs_used,[vsf_must_be_valid]);
+              set_varstate(p2,vs_read,[vsf_must_be_valid]);
               if assigned(p3) then
                 begin
                   resulttypepass(p3);
-                  set_varstate(p3,vs_used,[vsf_must_be_valid]);
+                  set_varstate(p3,vs_read,[vsf_must_be_valid]);
                 end;
               if codegenerror then
                break;
@@ -2467,8 +2467,8 @@ implementation
          resulttypepass(left);
          resulttypepass(right);
 
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
-         set_varstate(right,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
+         set_varstate(right,vs_read,[vsf_must_be_valid]);
 
          if codegenerror then
            exit;
@@ -2579,8 +2579,8 @@ implementation
          resulttypepass(right);
          resulttypepass(left);
 
-         set_varstate(right,vs_used,[vsf_must_be_valid]);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         set_varstate(right,vs_read,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
 
          if codegenerror then
            exit;

+ 10 - 7
compiler/nflw.pas

@@ -381,7 +381,7 @@ implementation
          { loop instruction }
          if assigned(right) then
            resulttypepass(right);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
          if codegenerror then
            exit;
 
@@ -559,7 +559,7 @@ implementation
          { else path }
          if assigned(t1) then
            resulttypepass(t1);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
          if codegenerror then
            exit;
 
@@ -834,7 +834,7 @@ implementation
                 cloadnode.create(current_procinfo.procdef.funcretsym,current_procinfo.procdef.funcretsym.owner),
                 left);
             resulttypepass(left);
-            set_varstate(left,vs_used,[vsf_must_be_valid]);
+            set_varstate(left,vs_read,[vsf_must_be_valid]);
           end;
         resulttype:=voidtype;
       end;
@@ -1175,7 +1175,7 @@ implementation
            begin
               { first para must be a _class_ }
               resulttypepass(left);
-              set_varstate(left,vs_used,[vsf_must_be_valid]);
+              set_varstate(left,vs_read,[vsf_must_be_valid]);
               if codegenerror then
                exit;
               if not(is_class(left.resulttype.def)) then
@@ -1304,16 +1304,19 @@ implementation
          resulttype:=voidtype;
 
          resulttypepass(left);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         // "try block" is "used"? (JM)
+         set_varstate(left,vs_readwritten,[vsf_must_be_valid]);
 
          resulttypepass(right);
-         set_varstate(right,vs_used,[vsf_must_be_valid]);
+         // "except block" is "used"? (JM)
+         set_varstate(right,vs_readwritten,[vsf_must_be_valid]);
 
          { special finally block only executed when there was an exception }
          if assigned(t1) then
            begin
              resulttypepass(t1);
-             set_varstate(t1,vs_used,[vsf_must_be_valid]);
+             // "finally block" is "used"? (JM)
+             set_varstate(t1,vs_readwritten,[vsf_must_be_valid]);
            end;
       end;
 

+ 34 - 34
compiler/ninl.pas

@@ -410,7 +410,7 @@ implementation
             left := filepara.right;
             filepara.right := nil;
             { the file para is a var parameter, but it must be valid already }
-            set_varstate(filepara.left,vs_used,[vsf_must_be_valid]);
+            set_varstate(filepara.left,vs_readwritten,[vsf_must_be_valid]);
             { check if we should make a temp to store the result of a complex }
             { expression (better heuristics, anyone?) (JM)                    }
             if (filepara.left.nodetype <> loadn) then
@@ -1328,7 +1328,7 @@ implementation
                      result:=hp;
                      goto myexit;
                    end;
-                  set_varstate(left,vs_used,[vsf_must_be_valid]);
+                  set_varstate(left,vs_read,[vsf_must_be_valid]);
                   if not is_integer(left.resulttype.def) then
                     CGMessage1(type_e_integer_expr_expected,left.resulttype.def.typename);
                   case inlinenumber of
@@ -1347,7 +1347,7 @@ implementation
 
               in_sizeof_x:
                 begin
-                  set_varstate(left,vs_used,[]);
+                  set_varstate(left,vs_read,[]);
                   if paramanager.push_high_param(vs_value,left.resulttype.def,current_procinfo.procdef.proccalloption) then
                    begin
                      hightree:=load_high_value_node(tparavarsym(tloadnode(left).symtableentry));
@@ -1368,7 +1368,7 @@ implementation
 
               in_typeof_x:
                 begin
-                  set_varstate(left,vs_used,[]);
+                  set_varstate(left,vs_read,[]);
                   resulttype:=voidpointertype;
                 end;
 
@@ -1381,7 +1381,7 @@ implementation
                       result:=hp;
                       goto myexit;
                     end;
-                   set_varstate(left,vs_used,[vsf_must_be_valid]);
+                   set_varstate(left,vs_read,[vsf_must_be_valid]);
                    case left.resulttype.def.deftype of
                      orddef :
                        begin
@@ -1445,7 +1445,7 @@ implementation
               in_chr_byte:
                 begin
                    { convert to explicit char() }
-                   set_varstate(left,vs_used,[vsf_must_be_valid]);
+                   set_varstate(left,vs_read,[vsf_must_be_valid]);
                    hp:=ctypeconvnode.create_internal(left,cchartype);
                    left:=nil;
                    result:=hp;
@@ -1453,7 +1453,7 @@ implementation
 
               in_length_x:
                 begin
-                  set_varstate(left,vs_used,[vsf_must_be_valid]);
+                  set_varstate(left,vs_read,[vsf_must_be_valid]);
 
                   case left.resulttype.def.deftype of
                     variantdef:
@@ -1565,7 +1565,7 @@ implementation
 
               in_typeinfo_x:
                 begin
-                   set_varstate(left,vs_used,[vsf_must_be_valid]);
+                   set_varstate(left,vs_read,[vsf_must_be_valid]);
                    resulttype:=voidpointertype;
                 end;
 
@@ -1589,7 +1589,7 @@ implementation
                     end;
                   { otherwise handle separately, because there could be a procvar, which }
                   { is 2*sizeof(pointer), while we must only check the first pointer     }
-                  set_varstate(tcallparanode(left).left,vs_used,[vsf_must_be_valid]);
+                  set_varstate(tcallparanode(left).left,vs_read,[vsf_must_be_valid]);
                   resulttype:=booltype;
                 end;
 
@@ -1598,7 +1598,7 @@ implementation
 
               in_seg_x :
                 begin
-                  set_varstate(left,vs_used,[]);
+                  set_varstate(left,vs_read,[]);
                   result:=cordconstnode.create(0,s32inttype,false);
                   goto myexit;
                 end;
@@ -1606,7 +1606,7 @@ implementation
               in_pred_x,
               in_succ_x:
                 begin
-                   set_varstate(left,vs_used,[vsf_must_be_valid]);
+                   set_varstate(left,vs_read,[vsf_must_be_valid]);
                    resulttype:=left.resulttype;
                    if not is_ordinal(resulttype.def) then
                      CGMessage(type_e_ordinal_expr_expected)
@@ -1649,8 +1649,8 @@ implementation
                   if assigned(left) then
                     begin
                        { first param must be var }
-                       valid_for_var(tcallparanode(left).left);
-                       set_varstate(tcallparanode(left).left,vs_used,[vsf_must_be_valid]);
+                       valid_for_var(tcallparanode(left).left,true);
+                       set_varstate(tcallparanode(left).left,vs_readwritten,[vsf_must_be_valid]);
 
                        if (left.resulttype.def.deftype in [enumdef,pointerdef]) or
                           is_ordinal(left.resulttype.def) or
@@ -1661,7 +1661,7 @@ implementation
                           { two paras ? }
                           if assigned(tcallparanode(left).right) then
                            begin
-                             set_varstate(tcallparanode(tcallparanode(left).right).left,vs_used,[vsf_must_be_valid]);
+                             set_varstate(tcallparanode(tcallparanode(left).right).left,vs_read,[vsf_must_be_valid]);
                              inserttypeconv_internal(tcallparanode(tcallparanode(left).right).left,tcallparanode(left).left.resulttype);
                              if assigned(tcallparanode(tcallparanode(left).right).right) then
                                CGMessage(parser_e_illegal_expression);
@@ -1717,14 +1717,14 @@ implementation
                   { the parser already checks whether we have two (and exectly two) }
                   { parameters (JM)                                                 }
                   { first param must be var }
-                  valid_for_var(tcallparanode(left).left);
-                  set_varstate(tcallparanode(left).left,vs_used,[vsf_must_be_valid]);
+                  valid_for_var(tcallparanode(left).left,true);
+                  set_varstate(tcallparanode(left).left,vs_readwritten,[vsf_must_be_valid]);
                   { check type }
                   if (left.resulttype.def.deftype=setdef) then
                     begin
                       { insert a type conversion       }
                       { to the type of the set elements  }
-                      set_varstate(tcallparanode(tcallparanode(left).right).left,vs_used,[vsf_must_be_valid]);
+                      set_varstate(tcallparanode(tcallparanode(left).right).left,vs_read,[vsf_must_be_valid]);
                       inserttypeconv(tcallparanode(tcallparanode(left).right).left,
                         tsetdef(left.resulttype.def).elementtype);
                     end
@@ -1765,13 +1765,13 @@ implementation
                            if is_open_array(left.resulttype.def) or
                               is_array_of_const(left.resulttype.def) then
                             begin
-                              set_varstate(left,vs_used,[vsf_must_be_valid]);
+                              set_varstate(left,vs_read,[vsf_must_be_valid]);
                               result:=load_high_value_node(tparavarsym(tloadnode(left).symtableentry));
                             end
                            else
                             if is_dynamic_array(left.resulttype.def) then
                               begin
-                                set_varstate(left,vs_used,[vsf_must_be_valid]);
+                                set_varstate(left,vs_read,[vsf_must_be_valid]);
                                 { can't use inserttypeconv because we need }
                                 { an explicit type conversion (JM)         }
                                 hp := ccallparanode.create(ctypeconvnode.create_internal(left,voidpointertype),nil);
@@ -1797,7 +1797,7 @@ implementation
                          begin
                            if is_open_string(left.resulttype.def) then
 			     begin
-                               set_varstate(left,vs_used,[vsf_must_be_valid]);
+                               set_varstate(left,vs_read,[vsf_must_be_valid]);
                                result:=load_high_value_node(tparavarsym(tloadnode(left).symtableentry))
 			     end
                            else
@@ -1824,7 +1824,7 @@ implementation
                     end
                   else
                     begin
-                      set_varstate(left,vs_used,[vsf_must_be_valid]);
+                      set_varstate(left,vs_read,[vsf_must_be_valid]);
                       inserttypeconv(left,pbestrealtype^);
                       resulttype:=pbestrealtype^;
                     end;
@@ -1845,7 +1845,7 @@ implementation
                     end
                   else
                     begin
-                      set_varstate(left,vs_used,[vsf_must_be_valid]);
+                      set_varstate(left,vs_read,[vsf_must_be_valid]);
                       inserttypeconv(left,pbestrealtype^);
                       resulttype:=s64inttype;
                     end;
@@ -1866,7 +1866,7 @@ implementation
                     end
                   else
                     begin
-                      set_varstate(left,vs_used,[vsf_must_be_valid]);
+                      set_varstate(left,vs_read,[vsf_must_be_valid]);
                       inserttypeconv(left,pbestrealtype^);
                       resulttype:=s64inttype;
                     end;
@@ -1878,7 +1878,7 @@ implementation
                     setconstrealvalue(frac(getconstrealvalue))
                   else
                     begin
-                      set_varstate(left,vs_used,[vsf_must_be_valid]);
+                      set_varstate(left,vs_read,[vsf_must_be_valid]);
                       inserttypeconv(left,pbestrealtype^);
                       resulttype:=pbestrealtype^;
                     end;
@@ -1890,7 +1890,7 @@ implementation
                     setconstrealvalue(int(getconstrealvalue))
                   else
                     begin
-                      set_varstate(left,vs_used,[vsf_must_be_valid]);
+                      set_varstate(left,vs_read,[vsf_must_be_valid]);
                       inserttypeconv(left,pbestrealtype^);
                       resulttype:=pbestrealtype^;
                     end;
@@ -1910,7 +1910,7 @@ implementation
                    setconstrealvalue(cos(getconstrealvalue))
                   else
                    begin
-                     set_varstate(left,vs_used,[vsf_must_be_valid]);
+                     set_varstate(left,vs_read,[vsf_must_be_valid]);
                      inserttypeconv(left,pbestrealtype^);
                      resulttype:=pbestrealtype^;
                    end;
@@ -1922,7 +1922,7 @@ implementation
                    setconstrealvalue(sin(getconstrealvalue))
                   else
                    begin
-                     set_varstate(left,vs_used,[vsf_must_be_valid]);
+                     set_varstate(left,vs_read,[vsf_must_be_valid]);
                      inserttypeconv(left,pbestrealtype^);
                      resulttype:=pbestrealtype^;
                    end;
@@ -1934,7 +1934,7 @@ implementation
                    setconstrealvalue(arctan(getconstrealvalue))
                   else
                    begin
-                     set_varstate(left,vs_used,[vsf_must_be_valid]);
+                     set_varstate(left,vs_read,[vsf_must_be_valid]);
                      inserttypeconv(left,pbestrealtype^);
                      resulttype:=pbestrealtype^;
                    end;
@@ -1946,7 +1946,7 @@ implementation
                    setconstrealvalue(abs(getconstrealvalue))
                   else
                    begin
-                     set_varstate(left,vs_used,[vsf_must_be_valid]);
+                     set_varstate(left,vs_read,[vsf_must_be_valid]);
                      inserttypeconv(left,pbestrealtype^);
                      resulttype:=pbestrealtype^;
                    end;
@@ -1958,7 +1958,7 @@ implementation
                    setconstrealvalue(sqr(getconstrealvalue))
                   else
                    begin
-                     set_varstate(left,vs_used,[vsf_must_be_valid]);
+                     set_varstate(left,vs_read,[vsf_must_be_valid]);
                      setfloatresulttype;
                    end;
                 end;
@@ -1975,7 +1975,7 @@ implementation
                    end
                   else
                    begin
-                     set_varstate(left,vs_used,[vsf_must_be_valid]);
+                     set_varstate(left,vs_read,[vsf_must_be_valid]);
                      setfloatresulttype;
                    end;
                 end;
@@ -1992,7 +1992,7 @@ implementation
                    end
                   else
                    begin
-                     set_varstate(left,vs_used,[vsf_must_be_valid]);
+                     set_varstate(left,vs_read,[vsf_must_be_valid]);
                      inserttypeconv(left,pbestrealtype^);
                      resulttype:=pbestrealtype^;
                    end;
@@ -2012,11 +2012,11 @@ implementation
                   resulttype:=voidtype;
                   if assigned(left) then
                     begin
-                       set_varstate(tcallparanode(left).left,vs_used,[vsf_must_be_valid]);
+                       set_varstate(tcallparanode(left).left,vs_read,[vsf_must_be_valid]);
                        { check type }
                        if is_boolean(left.resulttype.def) then
                          begin
-                            set_varstate(tcallparanode(tcallparanode(left).right).left,vs_used,[vsf_must_be_valid]);
+                            set_varstate(tcallparanode(tcallparanode(left).right).left,vs_read,[vsf_must_be_valid]);
                             { must always be a string }
                             inserttypeconv(tcallparanode(tcallparanode(left).right).left,cshortstringtype);
                          end

+ 6 - 6
compiler/nld.pas

@@ -576,8 +576,8 @@ implementation
           end;
 
         resulttypepass(right);
-        set_varstate(left,vs_assigned,[]);
-        set_varstate(right,vs_used,[vsf_must_be_valid]);
+        set_varstate(left,vs_written,[]);
+        set_varstate(right,vs_read,[vsf_must_be_valid]);
         if codegenerror then
           exit;
 
@@ -592,7 +592,7 @@ implementation
           CGMessage(type_e_operator_not_allowed);
 
         { test if node can be assigned, properties are allowed }
-        valid_for_assignment(left);
+        valid_for_assignment(left,true);
 
         { assigning nil to a dynamic array clears the array }
         if is_dynamic_array(left.resulttype.def) and
@@ -835,8 +835,8 @@ implementation
         result:=nil;
         resulttypepass(left);
         resulttypepass(right);
-        set_varstate(left,vs_used,[vsf_must_be_valid]);
-        set_varstate(right,vs_used,[vsf_must_be_valid]);
+        set_varstate(left,vs_read,[vsf_must_be_valid]);
+        set_varstate(right,vs_read,[vsf_must_be_valid]);
         if codegenerror then
          exit;
         resulttype:=left.resulttype;
@@ -900,7 +900,7 @@ implementation
            while assigned(hp) do
             begin
               resulttypepass(hp.left);
-              set_varstate(hp.left,vs_used,[vsf_must_be_valid]);
+              set_varstate(hp.left,vs_read,[vsf_must_be_valid]);
               if (htype.def=nil) then
                htype:=hp.left.resulttype
               else

+ 6 - 6
compiler/nmat.pas

@@ -144,8 +144,8 @@ implementation
          result:=nil;
          resulttypepass(left);
          resulttypepass(right);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
-         set_varstate(right,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
+         set_varstate(right,vs_read,[vsf_must_be_valid]);
          if codegenerror then
            exit;
 
@@ -475,8 +475,8 @@ implementation
          result:=nil;
          resulttypepass(left);
          resulttypepass(right);
-         set_varstate(right,vs_used,[vsf_must_be_valid]);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         set_varstate(right,vs_read,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
          if codegenerror then
            exit;
 
@@ -594,7 +594,7 @@ implementation
       begin
          result:=nil;
          resulttypepass(left);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
          if codegenerror then
            exit;
 
@@ -826,7 +826,7 @@ implementation
       begin
          result:=nil;
          resulttypepass(left);
-         set_varstate(left,vs_used,[]);
+         set_varstate(left,vs_read,[]);
          if codegenerror then
            exit;
 

+ 9 - 7
compiler/nmem.pas

@@ -430,7 +430,7 @@ implementation
             else
 {$endif i386}
               if (nf_internal in flags) or
-                 valid_for_addr(left) then
+                 valid_for_addr(left,true) then
                 begin
                   if not(nf_typedaddr in flags) then
                     resulttype:=voidpointertype
@@ -443,7 +443,9 @@ implementation
 
          { this is like the function addr }
          inc(parsing_para_level);
-         set_varstate(left,vs_used,[]);
+         { this is actually only "read", but treat it nevertheless as modified }
+         { due to the possible use of pointers                                 }
+         set_varstate(left,vs_readwritten,[]);
          dec(parsing_para_level);
       end;
 
@@ -482,7 +484,7 @@ implementation
       begin
          result:=nil;
          resulttypepass(left);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
          if codegenerror then
           exit;
 
@@ -660,10 +662,10 @@ implementation
                 is_ansistring(left.resulttype.def) or
                 is_widestring(left.resulttype.def);
          if valid then
-           set_varstate(left,vs_used,[vsf_must_be_valid])
+           set_varstate(left,vs_read,[vsf_must_be_valid])
          else
-           set_varstate(left,vs_used,[]);
-         set_varstate(right,vs_used,[vsf_must_be_valid]);
+           set_varstate(left,vs_read,[]);
+         set_varstate(right,vs_read,[vsf_must_be_valid]);
          if codegenerror then
           exit;
 
@@ -904,7 +906,7 @@ implementation
         resulttype:=voidtype;
 
         resulttypepass(withrefnode);
-        set_varstate(withrefnode,vs_used,[vsf_must_be_valid]);
+        set_varstate(withrefnode,vs_read,[vsf_must_be_valid]);
         if codegenerror then
          exit;
 

+ 6 - 6
compiler/nset.pas

@@ -142,7 +142,7 @@ implementation
          resulttypepass(left);
          if assigned(right) then
           resulttypepass(right);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
          if codegenerror then
           exit;
 
@@ -211,7 +211,7 @@ implementation
          result:=nil;
          resulttype:=booltype;
          resulttypepass(right);
-         set_varstate(right,vs_used,[vsf_must_be_valid]);
+         set_varstate(right,vs_read,[vsf_must_be_valid]);
          if codegenerror then
           exit;
 
@@ -238,7 +238,7 @@ implementation
            end;
 
          resulttypepass(left);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
          if codegenerror then
            exit;
 
@@ -344,8 +344,8 @@ implementation
          result:=nil;
          resulttypepass(left);
          resulttypepass(right);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
-         set_varstate(right,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
+         set_varstate(right,vs_read,[vsf_must_be_valid]);
          if codegenerror then
            exit;
          { both types must be compatible }
@@ -595,7 +595,7 @@ implementation
          expectloc:=LOC_VOID;
          { evalutes the case expression }
          firstpass(left);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
          if codegenerror then
            exit;
          registersint:=left.registersint;

+ 1 - 1
compiler/pdecvar.pas

@@ -654,7 +654,7 @@ implementation
               symtablestack.insert(tcsym);
               readtypedconst(tt,tcsym,false);
               { The variable has a value assigned }
-              vs.varstate:=vs_assigned;
+              vs.varstate:=vs_initialised;
             end
           else
             begin

+ 5 - 5
compiler/pinline.pas

@@ -79,9 +79,9 @@ implementation
         p:=comp_expr(true);
         { calc return type }
         if is_new then
-          set_varstate(p,vs_assigned,[])
+          set_varstate(p,vs_written,[])
         else
-          set_varstate(p,vs_used,[vsf_must_be_valid]);
+          set_varstate(p,vs_readwritten,[vsf_must_be_valid]);
         if (m_mac in aktmodeswitches) and
            is_class(p.resulttype.def) then
           begin
@@ -474,7 +474,7 @@ implementation
            ppn:=tcallparanode(paras);
            while assigned(ppn.right) do
             begin
-              set_varstate(ppn.left,vs_used,[vsf_must_be_valid]);
+              set_varstate(ppn.left,vs_read,[vsf_must_be_valid]);
               inserttypeconv(ppn.left,sinttype);
               inc(dims);
               ppn:=tcallparanode(ppn.right);
@@ -489,8 +489,8 @@ implementation
         { last param must be var }
         destppn:=ppn.left;
         inc(parsing_para_level);
-        valid_for_var(destppn);
-        set_varstate(destppn,vs_assigned,[]);
+        valid_for_var(destppn,true);
+        set_varstate(destppn,vs_written,[]);
         dec(parsing_para_level);
         { first param must be a string or dynamic array ...}
         isarray:=is_dynamic_array(destppn.resulttype.def);

+ 5 - 5
compiler/pstatmnt.pas

@@ -125,7 +125,7 @@ implementation
          caseexpr:=comp_expr(true);
          { determines result type }
          do_resulttypepass(caseexpr);
-         set_varstate(caseexpr,vs_used,[vsf_must_be_valid]);
+         set_varstate(caseexpr,vs_read,[vsf_must_be_valid]);
          casedeferror:=false;
          casedef:=caseexpr.resulttype.def;
          if (not assigned(casedef)) or
@@ -412,11 +412,11 @@ implementation
            needs to be done before the instruction block is
            parsed to have a valid hloopvar }
          resulttypepass(hfrom);
-         set_varstate(hfrom,vs_used,[vsf_must_be_valid]);
+         set_varstate(hfrom,vs_read,[vsf_must_be_valid]);
          resulttypepass(hto);
-         set_varstate(hto,vs_used,[vsf_must_be_valid]);
+         set_varstate(hto,vs_read,[vsf_must_be_valid]);
          resulttypepass(hloopvar);
-         set_varstate(hloopvar,vs_used,[]);
+         set_varstate(hloopvar,vs_readwritten,[]);
 
          { ... now the instruction block }
          hblock:=statement;
@@ -1170,7 +1170,7 @@ implementation
         }
         if assigned(current_procinfo.procdef.funcretsym) and
            (not paramanager.ret_in_param(current_procinfo.procdef.rettype.def,current_procinfo.procdef.proccalloption)) then
-          tabstractvarsym(current_procinfo.procdef.funcretsym).varstate:=vs_assigned;
+          tabstractvarsym(current_procinfo.procdef.funcretsym).varstate:=vs_initialised;
 
         { because the END is already read we need to get the
           last_endtoken_filepos here (PFV) }

+ 1 - 1
compiler/rautils.pas

@@ -801,7 +801,7 @@ Begin
       begin
         { we always assume in asm statements that     }
         { that the variable is valid.                 }
-        tabstractvarsym(sym).varstate:=vs_used;
+        tabstractvarsym(sym).varstate:=vs_readwritten;
         inc(tabstractvarsym(sym).refs);
         { variable can't be placed in a register }
         tabstractvarsym(sym).varregable:=vr_none;

+ 1 - 1
compiler/symconst.pas

@@ -363,7 +363,7 @@ type
 
   { State of the variable, if it's declared, assigned or used }
   tvarstate=(vs_none,
-    vs_declared,vs_assigned,vs_used
+    vs_declared,vs_initialised,vs_read,vs_written,vs_readwritten
   );
 
   tvarspez = (vs_value,vs_const,vs_var,vs_out);

+ 1 - 1
compiler/symsym.pas

@@ -1214,7 +1214,7 @@ implementation
     constructor tabstractvarsym.ppuload(ppufile:tcompilerppufile);
       begin
          inherited ppuload(ppufile);
-         varstate:=vs_used;
+         varstate:=vs_readwritten;
          varspez:=tvarspez(ppufile.getbyte);
          varregable:=tvarregable(ppufile.getbyte);
          ppufile.gettype(_vartype);

+ 1 - 1
compiler/symtable.pas

@@ -719,7 +719,7 @@ implementation
                 else
                   MessagePos1(tsym(p).fileinfo,sym_n_local_identifier_not_used,tsym(p).realname);
              end
-           else if tabstractvarsym(p).varstate=vs_assigned then
+           else if tabstractvarsym(p).varstate in [vs_written,vs_initialised] then
              begin
                 if (tsym(p).owner.symtabletype=parasymtable) then
                   begin