mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-12 18:49:46 +02:00
When checking whether the current specialization was already done before we also need to check the globalsymtable if we're currently in the implementation section. Otherwise the specialization will be generated twice and will result in a "duplicate identifier" error. This fixes mantis #20872 .
git-svn-id: trunk@19818 -
This commit is contained in:
parent
5ffba57b51
commit
fca525a85b
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -11955,6 +11955,9 @@ tests/webtbs/tw20796b.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw20796c.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw20821.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw20836.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw20872a.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw20872b.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw20872c.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
|
||||
|
@ -83,6 +83,7 @@ uses
|
||||
old_current_genericdef,old_current_specializedef : tstoreddef;
|
||||
tempst : tglobalsymtable;
|
||||
old_block_type: tblock_type;
|
||||
hashedid: thashedidstring;
|
||||
begin
|
||||
{ retrieve generic def that we are going to replace }
|
||||
genericdef:=tstoreddef(tt);
|
||||
@ -306,13 +307,28 @@ uses
|
||||
{ Can we reuse an already specialized type? }
|
||||
if not assigned(tt) then
|
||||
begin
|
||||
srsym:=tsym(specializest.find(uspecializename));
|
||||
hashedid.id:=uspecializename;
|
||||
|
||||
srsym:=tsym(specializest.findwithhash(hashedid));
|
||||
if assigned(srsym) then
|
||||
begin
|
||||
if srsym.typ<>typesym then
|
||||
internalerror(200710171);
|
||||
tt:=ttypesym(srsym).typedef;
|
||||
end;
|
||||
end
|
||||
else
|
||||
{ the generic could have been specialized in the globalsymtable
|
||||
already, so search there as well }
|
||||
if specializest<>current_module.globalsymtable then
|
||||
begin
|
||||
srsym:=tsym(current_module.globalsymtable.findwithhash(hashedid));
|
||||
if assigned(srsym) then
|
||||
begin
|
||||
if srsym.typ<>typesym then
|
||||
internalerror(2011121101);
|
||||
tt:=ttypesym(srsym).typedef;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
if not assigned(tt) then
|
||||
|
30
tests/webtbs/tw20872a.pp
Normal file
30
tests/webtbs/tw20872a.pp
Normal file
@ -0,0 +1,30 @@
|
||||
unit tw20872a;
|
||||
|
||||
{$MODE delphi}
|
||||
|
||||
interface
|
||||
|
||||
type
|
||||
TWrapper<TValue> = class end;
|
||||
|
||||
TTestClass = class
|
||||
strict private
|
||||
FWrapper: TWrapper<Integer>; { Using inline specialization }
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
constructor TTestClass.Create;
|
||||
begin
|
||||
FWrapper := TWrapper<Integer>.Create; { Duplicate identifier error here }
|
||||
end;
|
||||
|
||||
destructor TTestClass.Destroy;
|
||||
begin
|
||||
FWrapper.Free;
|
||||
end;
|
||||
|
||||
end.
|
32
tests/webtbs/tw20872b.pp
Normal file
32
tests/webtbs/tw20872b.pp
Normal file
@ -0,0 +1,32 @@
|
||||
unit tw20872b;
|
||||
|
||||
{$MODE delphi}
|
||||
|
||||
interface
|
||||
|
||||
type
|
||||
TWrapper<TValue> = class end;
|
||||
|
||||
TTestClass = class
|
||||
strict private
|
||||
type TSpecializedWrapper = TWrapper<Integer>;
|
||||
strict private
|
||||
FWrapper: TSpecializedWrapper; { Using traditional workaround }
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
constructor TTestClass.Create;
|
||||
begin
|
||||
FWrapper := TWrapper<Integer>.Create; { Duplicate identifier error here }
|
||||
end;
|
||||
|
||||
destructor TTestClass.Destroy;
|
||||
begin
|
||||
FWrapper.Free;
|
||||
end;
|
||||
|
||||
end.
|
35
tests/webtbs/tw20872c.pp
Normal file
35
tests/webtbs/tw20872c.pp
Normal file
@ -0,0 +1,35 @@
|
||||
unit tw20872c;
|
||||
|
||||
{$MODE delphi}
|
||||
|
||||
interface
|
||||
|
||||
type
|
||||
TWrapper<TValue> = class end;
|
||||
|
||||
TTestClass = class
|
||||
strict private
|
||||
type TSpecializedWrapper = TWrapper<Integer>;
|
||||
strict private
|
||||
FWrapper: TSpecializedWrapper; { Using traditional workaround }
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
constructor TTestClass.Create;
|
||||
type
|
||||
TLocalSpecializedWrapper =
|
||||
TWrapper<Integer>; { Duplicate identifier error here }
|
||||
begin
|
||||
FWrapper := TLocalSpecializedWrapper.Create;
|
||||
end;
|
||||
|
||||
destructor TTestClass.Destroy;
|
||||
begin
|
||||
FWrapper.Free;
|
||||
end;
|
||||
|
||||
end.
|
Loading…
Reference in New Issue
Block a user