mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 11:08:02 +02:00
When searching for the generic def of nested types inside specializations we first need to check local declarations inside the method if we are in one. Only then we may search inside the type's declaration. Fixes #20836 .
git-svn-id: trunk@19777 -
This commit is contained in:
parent
5824a0272b
commit
a1ef0add65
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -11942,6 +11942,7 @@ tests/webtbs/tw2069.pp svneol=native#text/plain
|
||||
tests/webtbs/tw20690.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw2072.pp svneol=native#text/plain
|
||||
tests/webtbs/tw20744.pp svneol=native#text/plain
|
||||
tests/webtbs/tw20836.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw2109.pp svneol=native#text/plain
|
||||
tests/webtbs/tw2110.pp svneol=native#text/plain
|
||||
tests/webtbs/tw2128.pp svneol=native#text/plain
|
||||
|
@ -363,6 +363,8 @@ implementation
|
||||
p:tnode;
|
||||
gendef : tstoreddef;
|
||||
s : shortstring;
|
||||
pd: tprocdef;
|
||||
hashedid : thashedidstring;
|
||||
begin
|
||||
old_block_type:=block_type;
|
||||
{ save unit container of forward declarations -
|
||||
@ -535,9 +537,31 @@ implementation
|
||||
if not assigned(current_structdef.genericdef) or
|
||||
not (current_structdef.genericdef.typ in [recorddef,objectdef]) then
|
||||
internalerror(2011052301);
|
||||
sym:=tsym(tabstractrecorddef(current_structdef.genericdef).symtable.Find(gentypename));
|
||||
hashedid.id:=gentypename;
|
||||
{ we could be inside a method of the specialization
|
||||
instead of its declaration, so check that first (as
|
||||
local nested types aren't allowed we don't need to
|
||||
walk the symtablestack to find the localsymtable) }
|
||||
if symtablestack.top.symtabletype=localsymtable then
|
||||
begin
|
||||
{ we are in a method }
|
||||
if not assigned(symtablestack.top.defowner) or
|
||||
(symtablestack.top.defowner.typ<>procdef) then
|
||||
internalerror(2011120701);
|
||||
pd:=tprocdef(symtablestack.top.defowner);
|
||||
if not assigned(pd.genericdef) or (pd.genericdef.typ<>procdef) then
|
||||
internalerror(2011120702);
|
||||
sym:=tsym(tprocdef(pd.genericdef).localst.findwithhash(hashedid));
|
||||
end
|
||||
else
|
||||
sym:=nil;
|
||||
if not assigned(sym) or not (sym.typ=typesym) then
|
||||
internalerror(2011052302);
|
||||
begin
|
||||
{ now search in the declaration of the generic }
|
||||
sym:=tsym(tabstractrecorddef(current_structdef.genericdef).symtable.findwithhash(hashedid));
|
||||
if not assigned(sym) or not (sym.typ=typesym) then
|
||||
internalerror(2011052302);
|
||||
end;
|
||||
{ use the corresponding type in the generic's symtable as
|
||||
genericdef for the specialized type }
|
||||
gendef:=tstoreddef(ttypesym(sym).typedef);
|
||||
|
29
tests/webtbs/tw20836.pp
Normal file
29
tests/webtbs/tw20836.pp
Normal file
@ -0,0 +1,29 @@
|
||||
program tw20836;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
uses
|
||||
{$IFDEF UNIX}{$IFDEF UseCThreads}
|
||||
cthreads,
|
||||
{$ENDIF}{$ENDIF}
|
||||
Classes
|
||||
{ you can add units after this };
|
||||
|
||||
{.$R *.res}
|
||||
type
|
||||
generic TGObjectChangeCommand<_T>=object
|
||||
private
|
||||
DoData,UnDoData:_T;
|
||||
method:tmethod;
|
||||
public
|
||||
procedure UnDo;virtual;
|
||||
end;
|
||||
TCommand=specialize TGObjectChangeCommand<Integer>;
|
||||
procedure TGObjectChangeCommand.UnDo;
|
||||
type
|
||||
TCangeMethod=procedure(const data:_T)of object;
|
||||
begin
|
||||
TCangeMethod(method)(UnDoData);
|
||||
end;
|
||||
begin
|
||||
end.
|
Loading…
Reference in New Issue
Block a user