mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-07-05 15:38:47 +02:00
* fix for Mantis #30761: always return the symbol found in the helper instead of doing this dependant on the presence of the overload attribute; for this the collection of all suitable overloads is done in tcallcandidates instead.
+ added test git-svn-id: trunk@35024 -
This commit is contained in:
parent
7f8cdc56d3
commit
d9ea6aae4d
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -15262,6 +15262,7 @@ tests/webtbs/tw3064.pp svneol=native#text/plain
|
|||||||
tests/webtbs/tw30666.pp svneol=native#text/plain
|
tests/webtbs/tw30666.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw30706.pp svneol=native#text/plain
|
tests/webtbs/tw30706.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw3073.pp svneol=native#text/plain
|
tests/webtbs/tw3073.pp svneol=native#text/plain
|
||||||
|
tests/webtbs/tw30761.pp svneol=native#text/pascal
|
||||||
tests/webtbs/tw3082.pp svneol=native#text/plain
|
tests/webtbs/tw3082.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw3083.pp svneol=native#text/plain
|
tests/webtbs/tw3083.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw30830a.pp svneol=native#text/pascal
|
tests/webtbs/tw30830a.pp svneol=native#text/pascal
|
||||||
|
@ -2172,6 +2172,9 @@ implementation
|
|||||||
|
|
||||||
procedure tcallcandidates.collect_overloads_in_struct(structdef:tabstractrecorddef;ProcdefOverloadList:TFPObjectList;searchhelpers,anoninherited:boolean;spezcontext:tspecializationcontext);
|
procedure tcallcandidates.collect_overloads_in_struct(structdef:tabstractrecorddef;ProcdefOverloadList:TFPObjectList;searchhelpers,anoninherited:boolean;spezcontext:tspecializationcontext);
|
||||||
|
|
||||||
|
var
|
||||||
|
changedhierarchy : boolean;
|
||||||
|
|
||||||
function processprocsym(srsym:tprocsym; out foundanything: boolean):boolean;
|
function processprocsym(srsym:tprocsym; out foundanything: boolean):boolean;
|
||||||
var
|
var
|
||||||
j : integer;
|
j : integer;
|
||||||
@ -2216,6 +2219,8 @@ implementation
|
|||||||
FProcsym:=tprocsym(srsym);
|
FProcsym:=tprocsym(srsym);
|
||||||
if po_overload in pd.procoptions then
|
if po_overload in pd.procoptions then
|
||||||
result:=true;
|
result:=true;
|
||||||
|
{ if the hierarchy had been changed we need to check for duplicates }
|
||||||
|
if not changedhierarchy or (ProcdefOverloadList.IndexOf(pd)<0) then
|
||||||
ProcdefOverloadList.Add(pd);
|
ProcdefOverloadList.Add(pd);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -2225,6 +2230,7 @@ implementation
|
|||||||
hashedid : THashedIDString;
|
hashedid : THashedIDString;
|
||||||
hasoverload,
|
hasoverload,
|
||||||
foundanything : boolean;
|
foundanything : boolean;
|
||||||
|
extendeddef : tabstractrecorddef;
|
||||||
helperdef : tobjectdef;
|
helperdef : tobjectdef;
|
||||||
begin
|
begin
|
||||||
if FOperator=NOTOKEN then
|
if FOperator=NOTOKEN then
|
||||||
@ -2232,6 +2238,8 @@ implementation
|
|||||||
else
|
else
|
||||||
hashedid.id:=overloaded_names[FOperator];
|
hashedid.id:=overloaded_names[FOperator];
|
||||||
hasoverload:=false;
|
hasoverload:=false;
|
||||||
|
extendeddef:=nil;
|
||||||
|
changedhierarchy:=false;
|
||||||
while assigned(structdef) do
|
while assigned(structdef) do
|
||||||
begin
|
begin
|
||||||
{ first search in helpers for this type }
|
{ first search in helpers for this type }
|
||||||
@ -2275,6 +2283,9 @@ implementation
|
|||||||
if is_objectpascal_helper(structdef) and
|
if is_objectpascal_helper(structdef) and
|
||||||
(tobjectdef(structdef).extendeddef.typ in [recorddef,objectdef]) then
|
(tobjectdef(structdef).extendeddef.typ in [recorddef,objectdef]) then
|
||||||
begin
|
begin
|
||||||
|
{ remember the first extendeddef of the hierarchy }
|
||||||
|
if not assigned(extendeddef) then
|
||||||
|
extendeddef:=tabstractrecorddef(tobjectdef(structdef).extendeddef);
|
||||||
{ search methods in the extended type as well }
|
{ search methods in the extended type as well }
|
||||||
srsym:=tprocsym(tabstractrecorddef(tobjectdef(structdef).extendeddef).symtable.FindWithHash(hashedid));
|
srsym:=tprocsym(tabstractrecorddef(tobjectdef(structdef).extendeddef).symtable.FindWithHash(hashedid));
|
||||||
if assigned(srsym) and
|
if assigned(srsym) and
|
||||||
@ -2293,6 +2304,13 @@ implementation
|
|||||||
structdef:=tobjectdef(structdef).childof
|
structdef:=tobjectdef(structdef).childof
|
||||||
else
|
else
|
||||||
structdef:=nil;
|
structdef:=nil;
|
||||||
|
{ switch over to the extended def's hierarchy }
|
||||||
|
if not assigned(structdef) and assigned(extendeddef) then
|
||||||
|
begin
|
||||||
|
structdef:=extendeddef;
|
||||||
|
extendeddef:=nil;
|
||||||
|
changedhierarchy:=true;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -3355,8 +3355,6 @@ implementation
|
|||||||
hashedid : THashedIDString;
|
hashedid : THashedIDString;
|
||||||
orgclass : tobjectdef;
|
orgclass : tobjectdef;
|
||||||
i : longint;
|
i : longint;
|
||||||
hlpsrsym : tsym;
|
|
||||||
hlpsrsymtable : tsymtable;
|
|
||||||
begin
|
begin
|
||||||
orgclass:=classh;
|
orgclass:=classh;
|
||||||
{ in case this is a formal class, first find the real definition }
|
{ in case this is a formal class, first find the real definition }
|
||||||
@ -3410,31 +3408,18 @@ implementation
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
hlpsrsym:=nil;
|
|
||||||
hlpsrsymtable:=nil;
|
|
||||||
while assigned(classh) do
|
while assigned(classh) do
|
||||||
begin
|
begin
|
||||||
{ search for a class helper method first if this is an Object
|
{ search for a class helper method first if this is an Object
|
||||||
Pascal class and we haven't yet found a helper symbol }
|
Pascal class and we haven't yet found a helper symbol }
|
||||||
if is_class(classh) and
|
if is_class(classh) and
|
||||||
(ssf_search_helper in flags) and
|
(ssf_search_helper in flags) then
|
||||||
not assigned(hlpsrsym) then
|
|
||||||
begin
|
begin
|
||||||
result:=search_objectpascal_helper(classh,contextclassh,s,srsym,srsymtable);
|
result:=search_objectpascal_helper(classh,contextclassh,s,srsym,srsymtable);
|
||||||
|
{ an eventual overload inside the extended type's hierarchy
|
||||||
|
will be found by tcallcandidates }
|
||||||
if result then
|
if result then
|
||||||
{ if the procsym is overloaded we need to use the
|
exit;
|
||||||
"original" symbol; the helper symbol will be found when
|
|
||||||
searching for overloads }
|
|
||||||
if (srsym.typ<>procsym) or
|
|
||||||
not (sp_has_overloaded in tprocsym(srsym).symoptions) then
|
|
||||||
exit
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
{ remember the found symbol if the class hierarchy
|
|
||||||
should not contain the a method with that name }
|
|
||||||
hlpsrsym:=srsym;
|
|
||||||
hlpsrsymtable:=srsymtable;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
srsymtable:=classh.symtable;
|
srsymtable:=classh.symtable;
|
||||||
srsym:=tsym(srsymtable.FindWithHash(hashedid));
|
srsym:=tsym(srsymtable.FindWithHash(hashedid));
|
||||||
@ -3448,15 +3433,6 @@ implementation
|
|||||||
end;
|
end;
|
||||||
classh:=classh.childof;
|
classh:=classh.childof;
|
||||||
end;
|
end;
|
||||||
{ did we find a helper symbol, but no symbol with the same name in
|
|
||||||
the extended object's hierarchy? }
|
|
||||||
if assigned(hlpsrsym) then
|
|
||||||
begin
|
|
||||||
srsym:=hlpsrsym;
|
|
||||||
srsymtable:=hlpsrsymtable;
|
|
||||||
result:=true;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
if is_objcclass(orgclass) then
|
if is_objcclass(orgclass) then
|
||||||
result:=search_objc_helper(orgclass,s,srsym,srsymtable)
|
result:=search_objc_helper(orgclass,s,srsym,srsymtable)
|
||||||
@ -3470,29 +3446,15 @@ implementation
|
|||||||
function searchsym_in_record(recordh:tabstractrecorddef;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
function searchsym_in_record(recordh:tabstractrecorddef;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
||||||
var
|
var
|
||||||
hashedid : THashedIDString;
|
hashedid : THashedIDString;
|
||||||
hlpsrsym : tsym;
|
|
||||||
hlpsrsymtable : tsymtable;
|
|
||||||
begin
|
begin
|
||||||
result:=false;
|
result:=false;
|
||||||
hlpsrsym:=nil;
|
|
||||||
hlpsrsymtable:=nil;
|
|
||||||
hashedid.id:=s;
|
hashedid.id:=s;
|
||||||
{ search for a record helper method first }
|
{ search for a record helper method first }
|
||||||
result:=search_objectpascal_helper(recordh,recordh,s,srsym,srsymtable);
|
result:=search_objectpascal_helper(recordh,recordh,s,srsym,srsymtable);
|
||||||
if result then
|
if result then
|
||||||
{ if the procsym is overloaded we need to use the
|
{ an eventual overload inside the extended type's hierarchy
|
||||||
"original" symbol; the helper symbol will be found when
|
will be found by tcallcandidates }
|
||||||
searching for overloads }
|
exit;
|
||||||
if (srsym.typ<>procsym) or
|
|
||||||
not (sp_has_overloaded in tprocsym(srsym).symoptions) then
|
|
||||||
exit
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
{ remember the found symbol if we should not find a symbol with
|
|
||||||
the same name in the extended record }
|
|
||||||
hlpsrsym:=srsym;
|
|
||||||
hlpsrsymtable:=srsymtable;
|
|
||||||
end;
|
|
||||||
srsymtable:=recordh.symtable;
|
srsymtable:=recordh.symtable;
|
||||||
srsym:=tsym(srsymtable.FindWithHash(hashedid));
|
srsym:=tsym(srsymtable.FindWithHash(hashedid));
|
||||||
if assigned(srsym) and is_visible_for_object(srsym,recordh) then
|
if assigned(srsym) and is_visible_for_object(srsym,recordh) then
|
||||||
@ -3501,9 +3463,8 @@ implementation
|
|||||||
result:=true;
|
result:=true;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
srsym:=hlpsrsym;
|
srsym:=nil;
|
||||||
srsymtable:=hlpsrsymtable;
|
srsymtable:=nil;
|
||||||
result:=assigned(srsym);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function searchsym_in_class_by_msgint(classh:tobjectdef;msgid:longint;out srdef : tdef;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
function searchsym_in_class_by_msgint(classh:tobjectdef;msgid:longint;out srdef : tdef;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
||||||
|
38
tests/webtbs/tw30761.pp
Normal file
38
tests/webtbs/tw30761.pp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{ %NORUN }
|
||||||
|
|
||||||
|
program tw30761;
|
||||||
|
|
||||||
|
{$mode objfpc}
|
||||||
|
|
||||||
|
type
|
||||||
|
Ta = class
|
||||||
|
public
|
||||||
|
procedure Test;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Tb = class(Ta)
|
||||||
|
end;
|
||||||
|
|
||||||
|
TbHelper = class helper for Tb
|
||||||
|
public
|
||||||
|
procedure Test(i: integer); overload;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure Ta.Test;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TbHelper.Test(i: integer);
|
||||||
|
begin
|
||||||
|
//Self.Test;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
b: Tb;
|
||||||
|
|
||||||
|
begin
|
||||||
|
b:=Tb.Create;
|
||||||
|
b.Test(1); // Error: Wrong number of parameters specified for call to "Test"
|
||||||
|
b.Test;
|
||||||
|
end.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user