Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion compiler/pexpr.pas
Original file line number Diff line number Diff line change
Expand Up @@ -4395,7 +4395,9 @@ if srsymtable.symtabletype=recordsymtable then
(sp_generic_dummy in srsym.symoptions) and
(current_scanner.token in [_LT,_LSHARPBRACKET]) then
begin
result:=cspecializenode.create(nil,getaddr,srsym,unit_found)
if not is_member_read(srsym,srsymtable,result,hdef) then
result:=nil;
result:=cspecializenode.create(result,getaddr,srsym,unit_found)
end
{ check if it's a method/class method }
else if is_member_read(srsym,srsymtable,result,hdef) then
Expand Down
138 changes: 138 additions & 0 deletions tests/webtbs/tw41711.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
program tw41711;

{$mode delphi}

type
TTarget = class
procedure CheckPlain;
procedure CheckGeneric<T>;
destructor Destroy; override;
end;

TOuter = class
procedure Invoke;
end;

TValue = record
Number: LongInt;
procedure SetPlain(AValue: LongInt);
procedure SetGeneric<T>(AValue: LongInt);
end;

var
Expected: TTarget;
Phase: LongInt;
ExplicitGenericMatches: LongInt;
WithVariableMatches: LongInt;
WithExpressionMatches: LongInt;
PlainWithMatches: LongInt;
WrongMatches: LongInt;
DestroyedTargets: LongInt;

procedure TTarget.CheckPlain;
begin
if Pointer(Self) = Pointer(Expected) then
Inc(PlainWithMatches)
else
Inc(WrongMatches);
end;

procedure TTarget.CheckGeneric<T>;
begin
if Pointer(Self) <> Pointer(Expected) then
begin
Inc(WrongMatches);
Exit;
end;
case Phase of
1: Inc(ExplicitGenericMatches);
2: Inc(WithVariableMatches);
3: Inc(WithExpressionMatches);
else
Inc(WrongMatches);
end;
end;

procedure TValue.SetPlain(AValue: LongInt);
begin
Self.Number := AValue;
end;

procedure TValue.SetGeneric<T>(AValue: LongInt);
begin
Self.Number := AValue + SizeOf(T);
end;

destructor TTarget.Destroy;
begin
Inc(DestroyedTargets);
inherited;
end;

function MakeTarget: TTarget;
begin
Result := TTarget.Create;
Expected := Result;
end;

procedure TOuter.Invoke;
var
Target: TTarget;
begin
Target := TTarget.Create;
try
Expected := Target;
Phase := 1;
Target.CheckGeneric<LongInt>;
Phase := 2;
with Target do
CheckGeneric<LongInt>;
with Target do
CheckPlain;
finally
Target.Free;
end;

Phase := 3;
with MakeTarget do
begin
CheckGeneric<LongInt>;
Free;
end;
end;

var
Outer: TOuter;
Value: TValue;
begin
Value.SetGeneric<Word>(20);
if Value.Number <> 22 then
Halt(7);
with Value do
SetGeneric<Byte>(10);
if Value.Number <> 11 then
Halt(8);
with Value do
SetPlain(30);
if Value.Number <> 30 then
Halt(9);

Outer := TOuter.Create;
try
Outer.Invoke;
finally
Outer.Free;
end;
if ExplicitGenericMatches <> 1 then
Halt(1);
if WithVariableMatches <> 1 then
Halt(2);
if WithExpressionMatches <> 1 then
Halt(3);
if PlainWithMatches <> 1 then
Halt(4);
if WrongMatches <> 0 then
Halt(5);
if DestroyedTargets <> 2 then
Halt(6);
end.
33 changes: 33 additions & 0 deletions tests/webtbs/tw41712.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
program tw41712;

{$mode delphi}

type
TTarget = class
procedure CheckGeneric<T>;
end;

var
Expected: TTarget;
Matches: LongInt;

procedure TTarget.CheckGeneric<T>;
begin
if Pointer(Self) = Pointer(Expected) then
Inc(Matches);
end;

var
Instance: TTarget;
begin
Instance := TTarget.Create;
try
Expected := Instance;
with Instance do
CheckGeneric<TObject>;
if Matches <> 1 then
Halt(1);
finally
Instance.Free;
end;
end.