mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-16 16:19:21 +02:00
* handle pointer+type param. correctly, resolves #19548
* convert exit(x) into result:=x; exit;, enables further optimizations in the future git-svn-id: trunk@17829 -
This commit is contained in:
parent
a2d007dfa3
commit
6e1d5e0aa0
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -11678,6 +11678,7 @@ tests/webtbs/tw1936.pp svneol=native#text/plain
|
|||||||
tests/webtbs/tw1938.pp svneol=native#text/plain
|
tests/webtbs/tw1938.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw1948.pp svneol=native#text/plain
|
tests/webtbs/tw1948.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw1950.pp svneol=native#text/plain
|
tests/webtbs/tw1950.pp svneol=native#text/plain
|
||||||
|
tests/webtbs/tw19548.pp svneol=native#text/pascal
|
||||||
tests/webtbs/tw1964.pp svneol=native#text/plain
|
tests/webtbs/tw1964.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw1996.pp svneol=native#text/plain
|
tests/webtbs/tw1996.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw2001.pp svneol=native#text/plain
|
tests/webtbs/tw2001.pp svneol=native#text/plain
|
||||||
|
@ -265,6 +265,9 @@ interface
|
|||||||
or not }
|
or not }
|
||||||
function is_nested_pd(def: tabstractprocdef): boolean;{$ifdef USEINLINE}inline;{$endif}
|
function is_nested_pd(def: tabstractprocdef): boolean;{$ifdef USEINLINE}inline;{$endif}
|
||||||
|
|
||||||
|
{ # returns whether def is a type parameter of a generic }
|
||||||
|
function is_typeparam(def : tdef) : boolean;{$ifdef USEINLINE}inline;{$endif}
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
@ -1142,4 +1145,8 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function is_typeparam(def : tdef) : boolean;{$ifdef USEINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
result:=(def.typ=undefineddef);
|
||||||
|
end;
|
||||||
end.
|
end.
|
||||||
|
@ -826,6 +826,13 @@ implementation
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
|
{ avoid any problems with type parameters later on }
|
||||||
|
if is_typeparam(left.resultdef) or is_typeparam(right.resultdef) then
|
||||||
|
begin
|
||||||
|
resultdef:=cundefinedtype;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
{ both left and right need to be valid }
|
{ both left and right need to be valid }
|
||||||
set_varstate(left,vs_read,[vsf_must_be_valid]);
|
set_varstate(left,vs_read,[vsf_must_be_valid]);
|
||||||
set_varstate(right,vs_read,[vsf_must_be_valid]);
|
set_varstate(right,vs_read,[vsf_must_be_valid]);
|
||||||
|
@ -1070,7 +1070,8 @@ implementation
|
|||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
if not is_boolean(left.resultdef) then
|
if not(is_boolean(left.resultdef)) and
|
||||||
|
not(is_typeparam(left.resultdef)) then
|
||||||
begin
|
begin
|
||||||
if left.resultdef.typ=variantdef then
|
if left.resultdef.typ=variantdef then
|
||||||
inserttypeconv(left,booltype)
|
inserttypeconv(left,booltype)
|
||||||
@ -1382,7 +1383,8 @@ implementation
|
|||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
if not is_boolean(left.resultdef) then
|
if not(is_boolean(left.resultdef)) and
|
||||||
|
not(is_typeparam(left.resultdef)) then
|
||||||
begin
|
begin
|
||||||
if left.resultdef.typ=variantdef then
|
if left.resultdef.typ=variantdef then
|
||||||
inserttypeconv(left,booltype)
|
inserttypeconv(left,booltype)
|
||||||
@ -1569,10 +1571,17 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
function texitnode.pass_typecheck:tnode;
|
function texitnode.pass_typecheck:tnode;
|
||||||
|
var
|
||||||
|
newstatement : tstatementnode;
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
if assigned(left) then
|
if assigned(left) then
|
||||||
typecheckpass(left);
|
begin
|
||||||
|
result:=internalstatements(newstatement);
|
||||||
|
addstatement(newstatement,left);
|
||||||
|
left:=nil;
|
||||||
|
addstatement(newstatement,self.getcopy);
|
||||||
|
end;
|
||||||
resultdef:=voidtype;
|
resultdef:=voidtype;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1582,11 +1591,7 @@ implementation
|
|||||||
result:=nil;
|
result:=nil;
|
||||||
expectloc:=LOC_VOID;
|
expectloc:=LOC_VOID;
|
||||||
if assigned(left) then
|
if assigned(left) then
|
||||||
begin
|
internalerror(2011052801);
|
||||||
firstpass(left);
|
|
||||||
if codegenerror then
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
21
tests/webtbs/tw19548.pp
Normal file
21
tests/webtbs/tw19548.pp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{$MODE OBJFPC} { -*- text -*- }
|
||||||
|
program tests;
|
||||||
|
|
||||||
|
type
|
||||||
|
generic TTest <PTest> = class
|
||||||
|
FPointer: PTest;
|
||||||
|
procedure Foo();
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTest.Foo();
|
||||||
|
var
|
||||||
|
Result: Boolean;
|
||||||
|
begin
|
||||||
|
Result := FPointer = nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
type
|
||||||
|
TPointerTest = specialize TTest <Pointer>;
|
||||||
|
|
||||||
|
begin
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user