* 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:
florian 2011-06-25 18:05:49 +00:00
parent a2d007dfa3
commit 6e1d5e0aa0
5 changed files with 49 additions and 8 deletions

1
.gitattributes vendored
View File

@ -11678,6 +11678,7 @@ tests/webtbs/tw1936.pp svneol=native#text/plain
tests/webtbs/tw1938.pp svneol=native#text/plain
tests/webtbs/tw1948.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/tw1996.pp svneol=native#text/plain
tests/webtbs/tw2001.pp svneol=native#text/plain

View File

@ -265,6 +265,9 @@ interface
or not }
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
uses
@ -1142,4 +1145,8 @@ implementation
end;
function is_typeparam(def : tdef) : boolean;{$ifdef USEINLINE}inline;{$endif}
begin
result:=(def.typ=undefineddef);
end;
end.

View File

@ -826,6 +826,13 @@ implementation
begin
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 }
set_varstate(left,vs_read,[vsf_must_be_valid]);
set_varstate(right,vs_read,[vsf_must_be_valid]);

View File

@ -1070,7 +1070,8 @@ implementation
if codegenerror then
exit;
if not is_boolean(left.resultdef) then
if not(is_boolean(left.resultdef)) and
not(is_typeparam(left.resultdef)) then
begin
if left.resultdef.typ=variantdef then
inserttypeconv(left,booltype)
@ -1382,7 +1383,8 @@ implementation
if codegenerror then
exit;
if not is_boolean(left.resultdef) then
if not(is_boolean(left.resultdef)) and
not(is_typeparam(left.resultdef)) then
begin
if left.resultdef.typ=variantdef then
inserttypeconv(left,booltype)
@ -1569,10 +1571,17 @@ implementation
function texitnode.pass_typecheck:tnode;
var
newstatement : tstatementnode;
begin
result:=nil;
if assigned(left) then
typecheckpass(left);
begin
result:=internalstatements(newstatement);
addstatement(newstatement,left);
left:=nil;
addstatement(newstatement,self.getcopy);
end;
resultdef:=voidtype;
end;
@ -1582,11 +1591,7 @@ implementation
result:=nil;
expectloc:=LOC_VOID;
if assigned(left) then
begin
firstpass(left);
if codegenerror then
exit;
end;
internalerror(2011052801);
end;

21
tests/webtbs/tw19548.pp Normal file
View 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.