Browse Source

* tcgvecnode, simplified range checking for strings. Removed FPC_*STR_CHECKZERO helpers, and changed FPC_*STR_CHECKRANGE so they accept the original left node. Now strings are checked the same way as dynamic arrays, and the compiler part is considerably simpler.

git-svn-id: trunk@17129 -
sergei 14 years ago
parent
commit
3e6ad5f5aa
5 changed files with 12 additions and 65 deletions
  1. 3 35
      compiler/ncgmem.pas
  2. 2 8
      rtl/inc/astrings.inc
  3. 3 6
      rtl/inc/compproc.inc
  4. 2 8
      rtl/inc/ustrings.inc
  5. 2 8
      rtl/inc/wstrings.inc

+ 3 - 35
compiler/ncgmem.pas

@@ -699,8 +699,6 @@ implementation
       var
       var
         paraloc1,
         paraloc1,
         paraloc2: tcgpara;
         paraloc2: tcgpara;
-        href: treference;
-        offsetdec: aint;
       begin
       begin
         paraloc1.init;
         paraloc1.init;
         paraloc2.init;
         paraloc2.init;
@@ -712,26 +710,9 @@ implementation
             begin
             begin
               paramanager.getintparaloc(pocall_default,1,paraloc1);
               paramanager.getintparaloc(pocall_default,1,paraloc1);
               paramanager.getintparaloc(pocall_default,2,paraloc2);
               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);
               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,paraloc1);
               paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc2);
               paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc2);
               cg.allocallcpuregisters(current_asmdata.CurrAsmList);
               cg.allocallcpuregisters(current_asmdata.CurrAsmList);
@@ -788,8 +769,7 @@ implementation
 
 
          { an ansistring needs to be dereferenced }
          { an ansistring needs to be dereferenced }
          if is_ansistring(left.resultdef) or
          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
            begin
               if nf_callunique in flags then
               if nf_callunique in flags then
                 internalerror(200304236);
                 internalerror(200304236);
@@ -816,18 +796,6 @@ implementation
                   internalerror(2002032218);
                   internalerror(2002032218);
               end;
               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] !! }
               { in ansistrings/widestrings S[1] is p<w>char(S)[0] !! }
               if is_ansistring(left.resultdef) then
               if is_ansistring(left.resultdef) then
                 offsetdec:=1
                 offsetdec:=1

+ 2 - 8
rtl/inc/astrings.inc

@@ -539,16 +539,10 @@ begin
 end;
 end;
 
 
 
 
-Procedure fpc_AnsiStr_CheckZero(p : pointer);[Public,Alias : 'FPC_ANSISTR_CHECKZERO'];  compilerproc;
-begin
-  if p=nil then
-    HandleErrorFrame(201,get_frame);
-end;
-
 
 
-Procedure fpc_AnsiStr_CheckRange(len,index : SizeInt);[Public,Alias : 'FPC_ANSISTR_RANGECHECK'];  compilerproc;
+Procedure fpc_AnsiStr_CheckRange(p: Pointer; index: SizeInt);[Public,Alias : 'FPC_ANSISTR_RANGECHECK'];  compilerproc;
 begin
 begin
-  if (index>len) or (Index<1) then
+  if (p=nil) or (index>PAnsiRec(p-FirstOff)^.Len) or (Index<1) then
     HandleErrorFrame(201,get_frame);
     HandleErrorFrame(201,get_frame);
 end;
 end;
 
 

+ 3 - 6
rtl/inc/compproc.inc

@@ -278,8 +278,7 @@ procedure fpc_ansistr_to_chararray(out res: array of char; const src: ansistring
 {$endif ndef FPC_STRTOCHARARRAYPROC}
 {$endif ndef FPC_STRTOCHARARRAYPROC}
 Function fpc_AnsiStr_Compare(const S1,S2 : AnsiString): SizeInt; compilerproc;
 Function fpc_AnsiStr_Compare(const S1,S2 : AnsiString): SizeInt; compilerproc;
 Function fpc_AnsiStr_Compare_equal(const S1,S2 : AnsiString): SizeInt; compilerproc;
 Function fpc_AnsiStr_Compare_equal(const S1,S2 : AnsiString): SizeInt; compilerproc;
-Procedure fpc_AnsiStr_CheckZero(p : pointer); compilerproc;
-Procedure fpc_AnsiStr_CheckRange(len,index : SizeInt); compilerproc;
+Procedure fpc_AnsiStr_CheckRange(p : Pointer; index : SizeInt); compilerproc;
 Procedure fpc_AnsiStr_SetLength (Var S : AnsiString; l : SizeInt); compilerproc;
 Procedure fpc_AnsiStr_SetLength (Var S : AnsiString; l : SizeInt); compilerproc;
 Function  fpc_ansistr_Copy (Const S : AnsiString; Index,Size : SizeInt) : AnsiString;compilerproc;
 Function  fpc_ansistr_Copy (Const S : AnsiString; Index,Size : SizeInt) : AnsiString;compilerproc;
 {$ifdef EXTRAANSISHORT}
 {$ifdef EXTRAANSISHORT}
@@ -327,8 +326,7 @@ procedure fpc_widestr_to_widechararray(out res: array of widechar; const src: Wi
 {$endif ndef FPC_STRTOCHARARRAYPROC}
 {$endif ndef FPC_STRTOCHARARRAYPROC}
 Function fpc_WideStr_Compare(const S1,S2 : WideString): SizeInt; compilerproc;
 Function fpc_WideStr_Compare(const S1,S2 : WideString): SizeInt; compilerproc;
 Function fpc_WideStr_Compare_equal(const S1,S2 : WideString): SizeInt; compilerproc;
 Function fpc_WideStr_Compare_equal(const S1,S2 : WideString): SizeInt; compilerproc;
-Procedure fpc_WideStr_CheckZero(p : pointer); compilerproc;
-Procedure fpc_WideStr_CheckRange(len,index : SizeInt); compilerproc;
+Procedure fpc_WideStr_CheckRange(p: Pointer; index : SizeInt); compilerproc;
 Procedure fpc_WideStr_SetLength (Var S : WideString; l : SizeInt); compilerproc;
 Procedure fpc_WideStr_SetLength (Var S : WideString; l : SizeInt); compilerproc;
 Function  fpc_widestr_Copy (Const S : WideString; Index,Size : SizeInt) : WideString;compilerproc;
 Function  fpc_widestr_Copy (Const S : WideString; Index,Size : SizeInt) : WideString;compilerproc;
 {$ifndef FPC_WINLIKEWIDESTRING}
 {$ifndef FPC_WINLIKEWIDESTRING}
@@ -413,8 +411,7 @@ procedure fpc_unicodestr_to_widechararray(out res: array of widechar; const src:
 {$endif VER2_2}
 {$endif VER2_2}
 Function fpc_UnicodeStr_Compare(const S1,S2 : UnicodeString): SizeInt; compilerproc;
 Function fpc_UnicodeStr_Compare(const S1,S2 : UnicodeString): SizeInt; compilerproc;
 Function fpc_UnicodeStr_Compare_equal(const S1,S2 : UnicodeString): SizeInt; compilerproc;
 Function fpc_UnicodeStr_Compare_equal(const S1,S2 : UnicodeString): SizeInt; compilerproc;
-Procedure fpc_UnicodeStr_CheckZero(p : pointer); compilerproc;
-Procedure fpc_UnicodeStr_CheckRange(len,index : SizeInt); compilerproc;
+Procedure fpc_UnicodeStr_CheckRange(p: Pointer; index : SizeInt); compilerproc;
 Procedure fpc_UnicodeStr_SetLength (Var S : UnicodeString; l : SizeInt); compilerproc;
 Procedure fpc_UnicodeStr_SetLength (Var S : UnicodeString; l : SizeInt); compilerproc;
 Function  fpc_unicodestr_Copy (Const S : UnicodeString; Index,Size : SizeInt) : UnicodeString;compilerproc;
 Function  fpc_unicodestr_Copy (Const S : UnicodeString; Index,Size : SizeInt) : UnicodeString;compilerproc;
 function fpc_unicodestr_Unique(Var S : Pointer): Pointer; compilerproc;
 function fpc_unicodestr_Unique(Var S : Pointer): Pointer; compilerproc;

+ 2 - 8
rtl/inc/ustrings.inc

@@ -1304,16 +1304,10 @@ begin
     exit(CompareWord(S1[1],S2[1],MaxI));
     exit(CompareWord(S1[1],S2[1],MaxI));
 end;
 end;
 
 
-Procedure fpc_UnicodeStr_CheckZero(p : pointer);[Public,Alias : 'FPC_UNICODESTR_CHECKZERO']; compilerproc;
-begin
-  if p=nil then
-    HandleErrorFrame(201,get_frame);
-end;
-
 
 
-Procedure fpc_UnicodeStr_CheckRange(len,index : SizeInt);[Public,Alias : 'FPC_UNICODESTR_RANGECHECK']; compilerproc;
+Procedure fpc_UnicodeStr_CheckRange(p: Pointer; index: SizeInt);[Public,Alias : 'FPC_UNICODESTR_RANGECHECK']; compilerproc;
 begin
 begin
-  if (index>len div 2) or (Index<1) then
+  if (p=nil) or (index>PUnicodeRec(p-UnicodeFirstOff)^.len div 2) or (Index<1) then
     HandleErrorFrame(201,get_frame);
     HandleErrorFrame(201,get_frame);
 end;
 end;
 
 

+ 2 - 8
rtl/inc/wstrings.inc

@@ -729,16 +729,10 @@ begin
     exit(CompareWord(S1[1],S2[1],MaxI));
     exit(CompareWord(S1[1],S2[1],MaxI));
 end;
 end;
 
 
-Procedure fpc_WideStr_CheckZero(p : pointer);[Public,Alias : 'FPC_WIDESTR_CHECKZERO']; compilerproc;
-begin
-  if p=nil then
-    HandleErrorFrame(201,get_frame);
-end;
-
 
 
-Procedure fpc_WideStr_CheckRange(len,index : SizeInt);[Public,Alias : 'FPC_WIDESTR_RANGECHECK']; compilerproc;
+Procedure fpc_WideStr_CheckRange(p: Pointer; index: SizeInt);[Public,Alias : 'FPC_WIDESTR_RANGECHECK']; compilerproc;
 begin
 begin
-  if (index>len div 2) or (Index<1) then
+  if (p=nil) or (index>PWideRec(p-WideFirstOff)^.len div 2) or (Index<1) then
     HandleErrorFrame(201,get_frame);
     HandleErrorFrame(201,get_frame);
 end;
 end;