diff --git a/compiler/alpha/radirect.pas b/compiler/alpha/radirect.pas index 68f56bc747..a10f287570 100644 --- a/compiler/alpha/radirect.pas +++ b/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; diff --git a/compiler/htypechk.pas b/compiler/htypechk.pas index 062a339be5..d55f822d85 100644 --- a/compiler/htypechk.pas +++ b/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.sizete_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, diff --git a/compiler/nadd.pas b/compiler/nadd.pas index d4e45c7cb3..47d179e295 100644 --- a/compiler/nadd.pas +++ b/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; diff --git a/compiler/ncal.pas b/compiler/ncal.pas index 4ea78a5d43..433512f9bf 100644 --- a/compiler/ncal.pas +++ b/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 diff --git a/compiler/ncnv.pas b/compiler/ncnv.pas index 7678f7060f..174f1334e8 100644 --- a/compiler/ncnv.pas +++ b/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; diff --git a/compiler/nflw.pas b/compiler/nflw.pas index ec078951cc..a4c2e04fd1 100644 --- a/compiler/nflw.pas +++ b/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; diff --git a/compiler/ninl.pas b/compiler/ninl.pas index d92b158657..88aad2780b 100644 --- a/compiler/ninl.pas +++ b/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 diff --git a/compiler/nld.pas b/compiler/nld.pas index 739629b580..1509cf7302 100644 --- a/compiler/nld.pas +++ b/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 diff --git a/compiler/nmat.pas b/compiler/nmat.pas index dffa161df7..168062b3db 100644 --- a/compiler/nmat.pas +++ b/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; diff --git a/compiler/nmem.pas b/compiler/nmem.pas index 0e47b4e53e..3f75360db3 100644 --- a/compiler/nmem.pas +++ b/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; diff --git a/compiler/nset.pas b/compiler/nset.pas index 94870d0166..491f6ce9bc 100644 --- a/compiler/nset.pas +++ b/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; diff --git a/compiler/pdecvar.pas b/compiler/pdecvar.pas index 626fdad9b2..0e3ef20457 100644 --- a/compiler/pdecvar.pas +++ b/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 diff --git a/compiler/pinline.pas b/compiler/pinline.pas index 27bed0aab8..98867f99e1 100644 --- a/compiler/pinline.pas +++ b/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); diff --git a/compiler/pstatmnt.pas b/compiler/pstatmnt.pas index 8109042fd3..1dcf6d86ba 100644 --- a/compiler/pstatmnt.pas +++ b/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) } diff --git a/compiler/rautils.pas b/compiler/rautils.pas index 6f3d57a4ab..f24611d748 100644 --- a/compiler/rautils.pas +++ b/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; diff --git a/compiler/symconst.pas b/compiler/symconst.pas index 3fad77b4d7..aa2569191b 100644 --- a/compiler/symconst.pas +++ b/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); diff --git a/compiler/symsym.pas b/compiler/symsym.pas index 71d8c093c8..bff1dd518c 100644 --- a/compiler/symsym.pas +++ b/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); diff --git a/compiler/symtable.pas b/compiler/symtable.pas index 3ff49c71c5..94c9bdf4cb 100644 --- a/compiler/symtable.pas +++ b/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