* accept dereferences in generics definitions, resolves #33700 properly

git-svn-id: trunk@39447 -
This commit is contained in:
florian 2018-07-13 21:00:33 +00:00
parent 52846df241
commit 93c5eae528
4 changed files with 90 additions and 3 deletions

1
.gitattributes vendored
View File

@ -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

View File

@ -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;

View File

@ -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
View 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.