tcgvecnode, cleanup/refactoring:

* Separated two almost identical parts of code into procedure rangecheck_string;
- Removed range checking of regular_array[constant], which should, according to the comments, happen in typecheckpass. tvecnode.pass_typecheck indeed does the necessary tests, so removing this duplicate check also eliminates duplicate warning when range checking is off.

git-svn-id: trunk@17124 -
This commit is contained in:
sergei 2011-03-12 21:40:10 +00:00
parent 7d5c4a0887
commit cf4c00e8d6

View File

@ -59,6 +59,7 @@ interface
function get_mul_size : aint;
private
procedure rangecheck_array;
procedure rangecheck_string;
protected
{# This routine is used to calculate the address of the reference.
On entry reg contains the index in the array,
@ -635,6 +636,10 @@ implementation
hreg : tregister;
paraloc1,paraloc2 : tcgpara;
begin
{ omit range checking when this is an array access to a pointer which has been
typecasted from an array }
if (ado_isconvertedpointer in tarraydef(left.resultdef).arrayoptions) then
exit;
paraloc1.init;
paraloc2.init;
if is_open_array(left.resultdef) or
@ -690,6 +695,64 @@ implementation
paraloc2.done;
end;
procedure tcgvecnode.rangecheck_string;
var
paraloc1,
paraloc2: tcgpara;
href: treference;
offsetdec: aint;
begin
paraloc1.init;
paraloc2.init;
case tstringdef(left.resultdef).stringtype of
{ it's the same for ansi- and wide strings }
st_unicodestring,
st_widestring,
st_ansistring:
begin
paramanager.getintparaloc(pocall_default,1,paraloc1);
paramanager.getintparaloc(pocall_default,2,paraloc2);
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,right.location,paraloc2);
href:=location.reference;
{ Add back the offset which was subtracted to map string[1]->pchar(string)[0] }
{ TODO: we'd better rangecheck on the original location, before offsetting it. }
if is_ansistring(left.resultdef) then
offsetdec:=1
else
offsetdec:=2;
if not(tf_winlikewidestring in target_info.flags) or
(tstringdef(left.resultdef).stringtype<>st_widestring) then
begin
dec(href.offset,sizeof(pint)-offsetdec);
cg.a_load_ref_cgpara(current_asmdata.CurrAsmList,OS_ADDR,href,paraloc1);
end
else
begin
{ winlike widestrings have a 4 byte length }
dec(href.offset,4-offsetdec);
cg.a_load_ref_cgpara(current_asmdata.CurrAsmList,OS_32,href,paraloc1);
end;
paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc2);
cg.allocallcpuregisters(current_asmdata.CurrAsmList);
cg.a_call_name(current_asmdata.CurrAsmList,'FPC_'+upper(tstringdef(left.resultdef).stringtypname)+'_RANGECHECK',false);
cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
end;
st_shortstring:
begin
{!!!!!!!!!!!!!!!!!}
{ if this one is implemented making use of the high parameter for openshortstrings, update ncgutils.do_get_used_regvars() too (JM) }
end;
st_longstring:
begin
{!!!!!!!!!!!!!!!!!}
end;
end;
paraloc1.done;
paraloc2.done;
end;
procedure tcgvecnode.pass_generate_code;
@ -697,7 +760,6 @@ implementation
offsetdec,
extraoffset : aint;
t : tnode;
href : treference;
otl,ofl : tasmlabel;
newsize : tcgsize;
mulsize,
@ -828,84 +890,16 @@ implementation
if right.nodetype=ordconstn then
begin
{ offset can only differ from 0 if arraydef }
case left.resultdef.typ of
arraydef :
begin
{ do not do any range checking when this is an array access to a pointer which has been
typecasted from an array }
if (not (ado_isconvertedpointer in tarraydef(left.resultdef).arrayoptions)) then
begin
if not(is_open_array(left.resultdef)) and
not(is_array_of_const(left.resultdef)) and
not(is_dynamic_array(left.resultdef)) then
begin
if (tordconstnode(right).value.svalue>tarraydef(left.resultdef).highrange) or
(tordconstnode(right).value.svalue<tarraydef(left.resultdef).lowrange) then
begin
{ this should be caught in the typecheckpass! (JM) }
if (cs_check_range in current_settings.localswitches) then
CGMessage(parser_e_range_check_error)
else
CGMessage(parser_w_range_check_error);
end;
end
else
begin
{ range checking for open and dynamic arrays needs
runtime code }
secondpass(right);
if (cs_check_range in current_settings.localswitches) then
rangecheck_array;
end;
end;
if cs_check_range in current_settings.localswitches then
begin
secondpass(right);
case left.resultdef.typ of
arraydef :
rangecheck_array;
stringdef :
rangecheck_string;
end;
stringdef :
begin
if (cs_check_range in current_settings.localswitches) then
begin
case tstringdef(left.resultdef).stringtype of
{ it's the same for ansi- and wide strings }
st_unicodestring,
st_widestring,
st_ansistring:
begin
paramanager.getintparaloc(pocall_default,1,paraloc1);
paramanager.getintparaloc(pocall_default,2,paraloc2);
cg.a_load_const_cgpara(current_asmdata.CurrAsmList,OS_INT,tordconstnode(right).value.svalue,paraloc2);
href:=location.reference;
if not(tf_winlikewidestring in target_info.flags) or
(tstringdef(left.resultdef).stringtype<>st_widestring) then
begin
dec(href.offset,sizeof(pint)-offsetdec);
cg.a_load_ref_cgpara(current_asmdata.CurrAsmList,OS_ADDR,href,paraloc1);
end
else
begin
{ winlike widestrings have a 4 byte length }
dec(href.offset,4-offsetdec);
cg.a_load_ref_cgpara(current_asmdata.CurrAsmList,OS_32,href,paraloc1);
end;
paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc2);
cg.allocallcpuregisters(current_asmdata.CurrAsmList);
cg.a_call_name(current_asmdata.CurrAsmList,'FPC_'+upper(tstringdef(left.resultdef).stringtypname)+'_RANGECHECK',false);
cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
end;
st_shortstring:
begin
{!!!!!!!!!!!!!!!!!}
{ if this one is implemented making use of the high parameter for openshortstrings, update ncgutils.do_get_used_regvars() too (JM) }
end;
st_longstring:
begin
{!!!!!!!!!!!!!!!!!}
end;
end;
end;
end;
end;
end;
if not(is_packed_array(left.resultdef)) or
((mulsize mod 8 = 0) and
(ispowerof2(mulsize div 8,temp) or
@ -1015,56 +1009,9 @@ implementation
if cs_check_range in current_settings.localswitches then
begin
if left.resultdef.typ=arraydef then
begin
{ do not do any range checking when this is an array access to a pointer which has been
typecasted from an array }
if (not (ado_isconvertedpointer in tarraydef(left.resultdef).arrayoptions)) then
rangecheck_array
end
rangecheck_array
else if (left.resultdef.typ=stringdef) then
begin
case tstringdef(left.resultdef).stringtype of
{ it's the same for ansi- and wide strings }
st_unicodestring,
st_widestring,
st_ansistring:
begin
paramanager.getintparaloc(pocall_default,1,paraloc1);
paramanager.getintparaloc(pocall_default,2,paraloc2);
cg.a_load_reg_cgpara(current_asmdata.CurrAsmList,OS_INT,right.location.register,paraloc2);
href:=location.reference;
dec(href.offset,sizeof(pint)-offsetdec);
href:=location.reference;
if not(tf_winlikewidestring in target_info.flags) or
(tstringdef(left.resultdef).stringtype<>st_widestring) then
begin
dec(href.offset,sizeof(pint)-offsetdec);
cg.a_load_ref_cgpara(current_asmdata.CurrAsmList,OS_ADDR,href,paraloc1);
end
else
begin
{ winlike widestrings have a 4 byte length }
dec(href.offset,4-offsetdec);
cg.a_load_ref_cgpara(current_asmdata.CurrAsmList,OS_32,href,paraloc1);
end;
paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc2);
cg.allocallcpuregisters(current_asmdata.CurrAsmList);
cg.a_call_name(current_asmdata.CurrAsmList,'FPC_'+upper(tstringdef(left.resultdef).stringtypname)+'_RANGECHECK',false);
cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
end;
st_shortstring:
begin
{!!!!!!!!!!!!!!!!!}
end;
st_longstring:
begin
{!!!!!!!!!!!!!!!!!}
end;
end;
end;
rangecheck_string;
end;
{ insert the register and the multiplication factor in the