summaryrefslogtreecommitdiff
path: root/compiler/ncgmem.pas
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/ncgmem.pas')
-rw-r--r--compiler/ncgmem.pas197
1 files changed, 56 insertions, 141 deletions
diff --git a/compiler/ncgmem.pas b/compiler/ncgmem.pas
index 1150c737bc..cad56ab507 100644
--- a/compiler/ncgmem.pas
+++ b/compiler/ncgmem.pas
@@ -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,45 @@ implementation
paraloc2.done;
end;
+ procedure tcgvecnode.rangecheck_string;
+ var
+ paraloc1,
+ paraloc2: tcgpara;
+ 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,left.location,paraloc1);
+ cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,right.location,paraloc2);
+
+ 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 +741,6 @@ implementation
offsetdec,
extraoffset : aint;
t : tnode;
- href : treference;
otl,ofl : tasmlabel;
newsize : tcgsize;
mulsize,
@@ -726,8 +769,7 @@ implementation
{ an ansistring needs to be dereferenced }
if is_ansistring(left.resultdef) or
- is_widestring(left.resultdef) or
- is_unicodestring(left.resultdef) then
+ is_wide_or_unicode_string(left.resultdef) then
begin
if nf_callunique in flags then
internalerror(200304236);
@@ -754,18 +796,6 @@ implementation
internalerror(2002032218);
end;
- { check for a zero length string,
- we can use the ansistring routine here }
- if (cs_check_range in current_settings.localswitches) then
- begin
- paramanager.getintparaloc(pocall_default,1,paraloc1);
- cg.a_load_reg_cgpara(current_asmdata.CurrAsmList,OS_ADDR,location.reference.base,paraloc1);
- paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
- cg.allocallcpuregisters(current_asmdata.CurrAsmList);
- cg.a_call_name(current_asmdata.CurrAsmList,'FPC_'+upper(tstringdef(left.resultdef).stringtypname)+'_CHECKZERO',false);
- cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
- end;
-
{ in ansistrings/widestrings S[1] is p<w>char(S)[0] !! }
if is_ansistring(left.resultdef) then
offsetdec:=1
@@ -828,84 +858,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 +977,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