+ optimize is operator if used on sealed classes as proposed in #30097

git-svn-id: trunk@38387 -
This commit is contained in:
florian 2018-02-28 22:09:24 +00:00
parent dc50511dce
commit 61053ead34
3 changed files with 62 additions and 3 deletions

1
.gitattributes vendored
View File

@ -11491,6 +11491,7 @@ tests/tbs/tb0636.pp svneol=native#text/pascal
tests/tbs/tb0637.pp svneol=native#text/pascal
tests/tbs/tb0638.pp svneol=native#text/pascal
tests/tbs/tb0639.pp svneol=native#text/pascal
tests/tbs/tb0641.pp svneol=native#text/pascal
tests/tbs/tb205.pp svneol=native#text/plain
tests/tbs/tb610.pp svneol=native#text/pascal
tests/tbs/tb613.pp svneol=native#text/plain

View File

@ -4307,6 +4307,8 @@ implementation
function tisnode.pass_1 : tnode;
var
procname: string;
statement : tstatementnode;
tempnode : ttempcreatenode;
begin
result:=nil;
{ Passing a class type to an "is" expression cannot result in a class
@ -4316,9 +4318,42 @@ implementation
if is_class(left.resultdef) and
(right.resultdef.typ=classrefdef) then
result := ccallnode.createinternres('fpc_do_is',
ccallparanode.create(left,ccallparanode.create(right,nil)),
resultdef)
begin
if (right.nodetype=loadvmtaddrn) and
(tloadvmtaddrnode(right).left.nodetype=typen) and
(oo_is_sealed in tobjectdef(tloadvmtaddrnode(right).left.resultdef).objectoptions) and
equal_defs(left.resultdef,tclassrefdef(right.resultdef).pointeddef) then
begin
if might_have_sideeffects(left) or
(node_complexity(left)>2) then
begin
result:=internalstatements(statement);
tempnode:=ctempcreatenode.create(left.resultdef,left.resultdef.size,tt_persistent,true);
addstatement(statement,tempnode);
addstatement(statement,cassignmentnode.create_internal(ctemprefnode.create(tempnode),left));
addstatement(statement,caddnode.create_internal(andn,
caddnode.create_internal(unequaln,ctemprefnode.create(tempnode),cnilnode.create),
caddnode.create_internal(equaln,cloadvmtaddrnode.create(ctemprefnode.create(tempnode)),right)
)
);
left:=nil;
right:=nil;
end
else
begin
result:=caddnode.create_internal(andn,
caddnode.create_internal(unequaln,left.getcopy,cnilnode.create),
caddnode.create_internal(equaln,cloadvmtaddrnode.create(left.getcopy),right)
);
right:=nil;
end;
end
else
result := ccallnode.createinternres('fpc_do_is',
ccallparanode.create(left,ccallparanode.create(right,nil)),
resultdef);
end
else
begin
if is_class(left.resultdef) then

23
tests/tbs/tb0641.pp Normal file
View File

@ -0,0 +1,23 @@
{$mode objfpc}
type
tc = class sealed
end;
var
c : tc;
function f : tc;
begin
result:=tc.create;
end;
begin
c:=tc.create;
if not(c is tc) then
halt(1);
if not(f is tc) then
halt(1);
writeln('ok');;
end.