* 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 -
This commit is contained in:
Jonas Maebe 2005-12-10 16:51:26 +00:00
parent 55d881615a
commit 42ec76598c
18 changed files with 192 additions and 147 deletions

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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) }

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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