* fix for Mantis #34333: improve error output for incorrect calls to Copy()

git-svn-id: trunk@39817 -
This commit is contained in:
svenbarth 2018-09-26 21:33:51 +00:00
parent cc354f9d72
commit 76c45b1a72
2 changed files with 82 additions and 26 deletions

View File

@ -1781,12 +1781,49 @@ implementation
function tinlinenode.handle_copy: tnode;
procedure do_error(typemismatch:boolean;func:string;fi:tfileposinfo);
procedure write_dynarray_copy;
begin
MessagePos1(fileinfo,sym_e_param_list,'Copy(Dynamic Array;'+sizesinttype.typename+'=`<low>`;'+sizesinttype.typename+'=`<length>`);');
end;
begin
if typemismatch then
CGMessagePos(fi,type_e_mismatch)
else
CGMessagePos1(fi,parser_e_wrong_parameter_size,'Copy');
if func='' then
begin
write_system_parameter_lists('fpc_shortstr_copy');
write_system_parameter_lists('fpc_char_copy');
write_system_parameter_lists('fpc_unicodestr_copy');
if tf_winlikewidestring in target_info.flags then
write_system_parameter_lists('fpc_widestr_copy');
write_system_parameter_lists('fpc_ansistr_copy');
write_dynarray_copy;
end
else if func='fpc_dynarray_copy' then
write_dynarray_copy
else
write_system_parameter_lists(func);
end;
var
paras : tnode;
ppn : tcallparanode;
paradef : tdef;
counter : integer;
minargs,
maxargs : longint;
func : string;
begin
if not assigned(left) then
begin
do_error(false,'',fileinfo);
exit(cerrornode.create);
end;
result:=nil;
{ determine copy function to use based on the first argument,
also count the number of arguments in this loop }
@ -1801,44 +1838,63 @@ implementation
end;
set_varstate(ppn.left,vs_read,[vsf_must_be_valid]);
paradef:=ppn.left.resultdef;
{ the string variants all require 2 or 3 args, only the array one allows less }
minargs:=2;
maxargs:=3;
if is_ansistring(paradef) then
// set resultdef to argument def
resultdef:=paradef
begin
// set resultdef to argument def
resultdef:=paradef;
func:='fpc_ansistr_copy';
end
else if (is_chararray(paradef) and (paradef.size>255)) or
((cs_refcountedstrings in current_settings.localswitches) and is_pchar(paradef)) then
// set resultdef to ansistring type since result will be in ansistring codepage
resultdef:=getansistringdef
else
if is_widestring(paradef) then
resultdef:=cwidestringtype
else
if is_unicodestring(paradef) or
begin
// set resultdef to ansistring type since result will be in ansistring codepage
resultdef:=getansistringdef;
func:='fpc_ansistr_copy';
end
else if is_widestring(paradef) then
begin
resultdef:=cwidestringtype;
func:='fpc_widestr_copy';
end
else if is_unicodestring(paradef) or
is_widechararray(paradef) or
is_pwidechar(paradef) then
resultdef:=cunicodestringtype
begin
resultdef:=cunicodestringtype;
func:='fpc_unicodestr_copy';
end
else
if is_char(paradef) then
resultdef:=cshortstringtype
begin
resultdef:=cshortstringtype;
func:='fpc_char_copy';
end
else
if is_dynamic_array(paradef) then
begin
{ Only allow 1 or 3 arguments }
if not(counter in [1..3]) then
begin
CGMessage1(parser_e_wrong_parameter_size,'Copy');
exit;
end;
minargs:=1;
resultdef:=paradef;
func:='fpc_dynarray_copy';
end
else if counter in [2..3] then
begin
resultdef:=cshortstringtype;
func:='fpc_shortstr_copy';
end
else
begin
{ generic fallback that will give an error if a wrong
type is passed }
if (counter=3) or (counter=2) then
resultdef:=cshortstringtype
else
CGMessagePos(ppn.left.fileinfo,type_e_mismatch);
end;
begin
do_error(true,'',ppn.left.fileinfo);
exit(cerrornode.create);
end;
if (counter<minargs) or (counter>maxargs) then
begin
do_error(false,func,fileinfo);
exit(cerrornode.create);
end;
end;
{$maxfpuregisters 0}

View File

@ -655,7 +655,7 @@ implementation
function inline_copy: tnode;
begin
result:=inline_copy_insert_delete(in_copy_x,'Copy',true);
result:=inline_copy_insert_delete(in_copy_x,'Copy',false);
end;