mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 08:48:08 +02:00
* reject overloads if they only differ in the result types (as long as they aren't operator overloads)
+ added tests git-svn-id: trunk@45973 -
This commit is contained in:
parent
fa0c9adbf4
commit
b62045809d
5
.gitattributes
vendored
5
.gitattributes
vendored
@ -15462,6 +15462,11 @@ tests/test/tover2.pp svneol=native#text/plain
|
||||
tests/test/tover3.pp svneol=native#text/plain
|
||||
tests/test/tover4.pas svneol=native#text/plain
|
||||
tests/test/tover4.pp svneol=native#text/plain
|
||||
tests/test/tover5.pp svneol=native#text/pascal
|
||||
tests/test/tover6.pp svneol=native#text/pascal
|
||||
tests/test/tover7.pp svneol=native#text/pascal
|
||||
tests/test/tover8.pp svneol=native#text/pascal
|
||||
tests/test/tover9.pp svneol=native#text/pascal
|
||||
tests/test/tpackrec.pp svneol=native#text/plain
|
||||
tests/test/tparray1.pp svneol=native#text/plain
|
||||
tests/test/tparray10.pp svneol=native#text/plain
|
||||
|
@ -676,16 +676,18 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function equal_generic_procdefs(fwpd,currpd:tprocdef):boolean;
|
||||
function equal_generic_procdefs(fwpd,currpd:tprocdef;out sameparas,sameret:boolean):boolean;
|
||||
var
|
||||
i : longint;
|
||||
fwsym,
|
||||
currsym : tsym;
|
||||
fwtype : ttypesym absolute fwsym;
|
||||
currtype : ttypesym absolute currsym;
|
||||
foundretdef : boolean;
|
||||
convdummy: tconverttype;
|
||||
pddummy: tprocdef;
|
||||
begin
|
||||
result:=false;
|
||||
sameparas:=false;
|
||||
sameret:=false;
|
||||
if fwpd.genericparas.count<>currpd.genericparas.count then
|
||||
exit;
|
||||
{ comparing generic declarations is a bit more cumbersome as the
|
||||
@ -696,7 +698,6 @@ implementation
|
||||
constraints while currpd must only contain undefineddefs
|
||||
- forward declaration in implementation: here constraints must be
|
||||
repeated }
|
||||
foundretdef:=false;
|
||||
for i:=0 to fwpd.genericparas.count-1 do
|
||||
begin
|
||||
fwsym:=tsym(fwpd.genericparas[i]);
|
||||
@ -728,28 +729,32 @@ implementation
|
||||
as well }
|
||||
exit;
|
||||
end;
|
||||
if not foundretdef and (fwsym.typ=typesym) then
|
||||
begin
|
||||
{ if the returndef is the same as this parameter's def then this
|
||||
needs to be the case for both procdefs }
|
||||
foundretdef:=fwpd.returndef=fwtype.typedef;
|
||||
if foundretdef xor (currpd.returndef=currtype.typedef) then
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
if compare_paras(fwpd.paras,currpd.paras,cp_none,[cpo_ignorehidden,cpo_openequalisexact,cpo_ignoreuniv,cpo_generic])<>te_exact then
|
||||
exit;
|
||||
if not foundretdef then
|
||||
begin
|
||||
if (df_specialization in tstoreddef(fwpd.returndef).defoptions) and (df_specialization in tstoreddef(currpd.returndef).defoptions) then
|
||||
{ for specializations we're happy with equal defs instead of exactly the same defs }
|
||||
result:=equal_defs(fwpd.returndef,currpd.returndef)
|
||||
else
|
||||
{ the returndef isn't a type parameter, so compare as usual }
|
||||
result:=compare_defs(fwpd.returndef,currpd.returndef,nothingn)=te_exact;
|
||||
end
|
||||
sameparas:=true;
|
||||
if (df_specialization in tstoreddef(fwpd.returndef).defoptions) and (df_specialization in tstoreddef(currpd.returndef).defoptions) then
|
||||
{ for specializations we're happy with equal defs instead of exactly the same defs }
|
||||
result:=equal_defs(fwpd.returndef,currpd.returndef)
|
||||
else
|
||||
result:=true;
|
||||
begin
|
||||
{ strictly compare defs using compare_defs_ext, but allow
|
||||
non exactly equal undefineddefs }
|
||||
convdummy:=tc_none;
|
||||
pddummy:=nil;
|
||||
result:=(compare_defs_ext(fwpd.returndef,currpd.returndef,nothingn,convdummy,pddummy,[cdo_allow_variant,cdo_strict_undefined_check])=te_exact) or
|
||||
equal_genfunc_paradefs(fwpd.returndef,currpd.returndef,fwpd.parast,currpd.parast);
|
||||
end;
|
||||
{ the result variable is only set depending on the return type, so we
|
||||
can simply use "result" }
|
||||
sameret:=result;
|
||||
end;
|
||||
|
||||
function equal_signature(fwpd,currpd:tprocdef;out sameparas,sameret:boolean):boolean;
|
||||
begin
|
||||
sameparas:=compare_paras(fwpd.paras,currpd.paras,cp_none,[cpo_ignorehidden,cpo_openequalisexact,cpo_ignoreuniv])=te_exact;
|
||||
sameret:=compare_defs(fwpd.returndef,currpd.returndef,nothingn)=te_exact;
|
||||
result:=sameparas and sameret;
|
||||
end;
|
||||
|
||||
{
|
||||
@ -767,6 +772,11 @@ implementation
|
||||
i : longint;
|
||||
po_comp : tprocoptions;
|
||||
paracompopt: tcompare_paras_options;
|
||||
sameparasfound,
|
||||
gensameparas,
|
||||
gensameret,
|
||||
sameparas,
|
||||
sameret,
|
||||
forwardfound : boolean;
|
||||
symentry: TSymEntry;
|
||||
item : tlinkedlistitem;
|
||||
@ -781,6 +791,9 @@ implementation
|
||||
exit;
|
||||
end;
|
||||
|
||||
sameparasfound:=false;
|
||||
fwpd:=nil;
|
||||
|
||||
{ check overloaded functions if the same function already exists }
|
||||
for i:=0 to tprocsym(currpd.procsym).ProcdefList.Count-1 do
|
||||
begin
|
||||
@ -797,6 +810,11 @@ implementation
|
||||
if fwpd.procsym<>currpd.procsym then
|
||||
continue;
|
||||
|
||||
gensameparas:=false;
|
||||
gensameret:=false;
|
||||
sameparas:=false;
|
||||
sameret:=false;
|
||||
|
||||
{ check the parameters, for delphi/tp it is possible to
|
||||
leave the parameters away in the implementation (forwarddef=false).
|
||||
But for an overload declared function this is not allowed }
|
||||
@ -810,7 +828,7 @@ implementation
|
||||
(
|
||||
fwpd.is_generic and
|
||||
currpd.is_generic and
|
||||
equal_generic_procdefs(fwpd,currpd)
|
||||
equal_generic_procdefs(fwpd,currpd,gensameparas,gensameret)
|
||||
) or
|
||||
{ check arguments, we need to check only the user visible parameters. The hidden parameters
|
||||
can be in a different location because of the calling convention, eg. L-R vs. R-L order (PFV)
|
||||
@ -819,8 +837,9 @@ implementation
|
||||
values should be reported as mismatches (since you can't overload based on different default
|
||||
parameter values) }
|
||||
(
|
||||
(compare_paras(fwpd.paras,currpd.paras,cp_none,[cpo_ignorehidden,cpo_openequalisexact,cpo_ignoreuniv])=te_exact) and
|
||||
(compare_defs(fwpd.returndef,currpd.returndef,nothingn)=te_exact)
|
||||
not fwpd.is_generic and
|
||||
not currpd.is_generic and
|
||||
equal_signature(fwpd,currpd,sameparas,sameret)
|
||||
) then
|
||||
begin
|
||||
{ Check if we've found the forwarddef, if found then
|
||||
@ -897,7 +916,7 @@ implementation
|
||||
(
|
||||
fwpd.is_generic and
|
||||
currpd.is_generic and
|
||||
not equal_generic_procdefs(fwpd,currpd)
|
||||
not equal_generic_procdefs(fwpd,currpd,sameparas,sameret)
|
||||
) or
|
||||
(
|
||||
(
|
||||
@ -1124,8 +1143,24 @@ implementation
|
||||
end;
|
||||
end;
|
||||
end; { equal arguments }
|
||||
|
||||
{ we found a match with the same parameter signature, but mismatching
|
||||
return types; complain about that, but only once we've checked for
|
||||
a forward to improve error recovery }
|
||||
if (sameparas and not sameret and
|
||||
{ ensure that specifiers are the same as well }
|
||||
(compare_paras(fwpd.paras,currpd.paras,cp_all,[cpo_ignorehidden,cpo_openequalisexact,cpo_ignoreuniv])=te_exact)
|
||||
) or (gensameparas and not gensameret) then
|
||||
sameparasfound:=true;
|
||||
end;
|
||||
|
||||
if sameparasfound and
|
||||
not (currpd.proctypeoption=potype_operator) then
|
||||
begin
|
||||
MessagePos(currpd.fileinfo,parser_e_overloaded_have_same_parameters);
|
||||
tprocsym(currpd.procsym).write_parameter_lists(currpd);
|
||||
end;
|
||||
|
||||
{ if we didn't reuse a forwarddef then we add the procdef to the overloaded
|
||||
list }
|
||||
if not forwardfound then
|
||||
|
22
tests/test/tover5.pp
Normal file
22
tests/test/tover5.pp
Normal file
@ -0,0 +1,22 @@
|
||||
{ %FAIL }
|
||||
|
||||
program tover5;
|
||||
|
||||
{$mode objfpc}
|
||||
|
||||
type
|
||||
TTestClass = class
|
||||
procedure Test(aArg1: LongInt);
|
||||
function Test(aArg1: LongInt): LongInt;
|
||||
end;
|
||||
|
||||
procedure TTestClass.Test(aArg1: LongInt);
|
||||
begin
|
||||
end;
|
||||
|
||||
function TTestClass.Test(aArg1: Longint): LongInt;
|
||||
begin
|
||||
end;
|
||||
|
||||
begin
|
||||
end.
|
25
tests/test/tover6.pp
Normal file
25
tests/test/tover6.pp
Normal file
@ -0,0 +1,25 @@
|
||||
{ %FAIL }
|
||||
|
||||
unit tover6;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
procedure Test(aArg: LongInt);
|
||||
function Test(aArg: LongInt): LongInt;
|
||||
|
||||
implementation
|
||||
|
||||
procedure Test(aArg: LongInt);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
function Test(aArg: LongInt): LongInt;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
end.
|
||||
|
17
tests/test/tover7.pp
Normal file
17
tests/test/tover7.pp
Normal file
@ -0,0 +1,17 @@
|
||||
{ %FAIL }
|
||||
|
||||
program tover7;
|
||||
|
||||
{$mode objfpc}
|
||||
|
||||
procedure Test(aArg: LongInt);
|
||||
begin
|
||||
end;
|
||||
|
||||
function Test(aArg: LongInt): LongInt;
|
||||
begin
|
||||
end;
|
||||
|
||||
begin
|
||||
|
||||
end.
|
17
tests/test/tover8.pp
Normal file
17
tests/test/tover8.pp
Normal file
@ -0,0 +1,17 @@
|
||||
{ %FAIL }
|
||||
|
||||
program tover8;
|
||||
|
||||
{$mode objfpc}
|
||||
|
||||
generic procedure Test<T>(aArg: T);
|
||||
begin
|
||||
end;
|
||||
|
||||
generic function Test<T>(aArg: T): T;
|
||||
begin
|
||||
end;
|
||||
|
||||
begin
|
||||
|
||||
end.
|
40
tests/test/tover9.pp
Normal file
40
tests/test/tover9.pp
Normal file
@ -0,0 +1,40 @@
|
||||
unit tover9;
|
||||
|
||||
{$mode objfpc}
|
||||
|
||||
interface
|
||||
|
||||
{ this is the for xmlSchemaSetParserErrors in the xmlschemas.inc of the libxml
|
||||
package }
|
||||
|
||||
procedure Test(aArg: PLongInt);
|
||||
function Test(var aArg: LongInt): LongInt;
|
||||
|
||||
{ also check generic routines just to be sure }
|
||||
|
||||
generic procedure Test2<T>(aArg: PLongInt);
|
||||
generic function Test2<T>(var aArg: LongInt): LongInt;
|
||||
|
||||
implementation
|
||||
|
||||
procedure Test(aArg: PLongInt);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
function Test(var aArg: LongInt): LongInt;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
generic procedure Test2<T>(aArg: PLongInt);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
generic function Test2<T>(var aArg: LongInt): LongInt;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
end.
|
Loading…
Reference in New Issue
Block a user