mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-11 04:01:37 +02:00
* accept dereferences in generics definitions, resolves #33700 properly
git-svn-id: trunk@39447 -
This commit is contained in:
parent
52846df241
commit
93c5eae528
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -16210,6 +16210,7 @@ tests/webtbs/tw33635.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw3364.pp svneol=native#text/plain
|
||||
tests/webtbs/tw3366.pp svneol=native#text/plain
|
||||
tests/webtbs/tw33696.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw33700.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw33706.pp svneol=native#text/plain
|
||||
tests/webtbs/tw33818.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw33839a.pp -text svneol=native#text/pascal
|
||||
|
@ -769,9 +769,11 @@ implementation
|
||||
maybe_call_procvar(left,true);
|
||||
|
||||
if left.resultdef.typ=pointerdef then
|
||||
resultdef:=tpointerdef(left.resultdef).pointeddef
|
||||
resultdef:=tpointerdef(left.resultdef).pointeddef
|
||||
else if left.resultdef.typ=undefineddef then
|
||||
resultdef:=cundefineddef.create(true)
|
||||
else
|
||||
CGMessage(parser_e_invalid_qualifier);
|
||||
CGMessage(parser_e_invalid_qualifier);
|
||||
end;
|
||||
|
||||
procedure Tderefnode.mark_write;
|
||||
|
@ -2034,7 +2034,7 @@ implementation
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else if (p1.resultdef.typ<>pointerdef) then
|
||||
else if not(p1.resultdef.typ in [pointerdef,undefineddef]) then
|
||||
begin
|
||||
{ ^ as binary operator is a problem!!!! (FK) }
|
||||
again:=false;
|
||||
|
84
tests/webtbs/tw33700.pp
Normal file
84
tests/webtbs/tw33700.pp
Normal file
@ -0,0 +1,84 @@
|
||||
program testbug;
|
||||
{$mode delphi}{$H+}
|
||||
type
|
||||
PLstGrandTyp = ^TLstGrandForwardTyp;
|
||||
|
||||
TLstGrandForwardTyp = packed record
|
||||
early, Next: PLstGrandTyp;
|
||||
end;
|
||||
|
||||
|
||||
PLstTyp01 = ^TLstForwardTyp01;
|
||||
TLstForwardTyp01 = packed record
|
||||
early, Next: PLstTyp01;
|
||||
Value: byte;
|
||||
end;
|
||||
|
||||
PLstTyp02 = ^TLstForwardTyp02;
|
||||
TLstForwardTyp02 = packed record
|
||||
early, Next: PLstTyp02;
|
||||
Value: string[255];
|
||||
end;
|
||||
|
||||
TLstEnumerator<T> = record
|
||||
private
|
||||
lst, lst_save: T;
|
||||
public
|
||||
constructor Create(const Value: T);
|
||||
function GetEnumerator: TLstEnumerator<T>;
|
||||
function MoveNext: boolean;
|
||||
property Current: T read lst;
|
||||
end;
|
||||
|
||||
constructor TLstEnumerator<T>.Create(const Value: T);
|
||||
begin
|
||||
lst := Value;
|
||||
lst_save := nil;
|
||||
end;
|
||||
|
||||
function TLstEnumerator<T>.GetEnumerator: TLstEnumerator<T>;
|
||||
begin
|
||||
Result := Self;
|
||||
end;
|
||||
|
||||
function TLstEnumerator<T>.MoveNext: boolean;
|
||||
begin
|
||||
if lst <> nil then
|
||||
begin
|
||||
// At this point it is simply not known that lst is a type that has
|
||||
// a field called next. So the compiler throws an illegal qualifier.
|
||||
// The compiler is correct. This is not a bug!
|
||||
lst:=lst^.next;
|
||||
Result := True;
|
||||
end else Result := False;
|
||||
end;
|
||||
|
||||
|
||||
var
|
||||
i01:PLstTyp01 = nil;
|
||||
lst01: PLstTyp01 = nil;
|
||||
i02:PlstTyp02 = nil;
|
||||
lst02: PLstTyp02 = nil;
|
||||
i03:PlstGrandTyp = nil;
|
||||
lst03: PLstGrandTyp = nil;
|
||||
en01: TLstEnumerator<PLstTyp01>;
|
||||
en02: TLstEnumerator<PLstTyp02>;
|
||||
en03: TLstEnumerator<PLstGrandTyp>;
|
||||
begin
|
||||
|
||||
for i01 in en01.Create(lst01) do
|
||||
begin
|
||||
i01^.Value := 10;
|
||||
end;
|
||||
|
||||
for i02 in en02.Create(lst02) do
|
||||
begin
|
||||
i02^.Value := 'ten';
|
||||
end;
|
||||
|
||||
for i03 in en03.Create(lst03) do
|
||||
begin
|
||||
end;
|
||||
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user