mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-05 09:38:47 +02:00
* forbid passing derived classes to call by reference parent classes (for objects, this is still allowed), resolves #13135
git-svn-id: trunk@13551 -
This commit is contained in:
parent
e7c9a380f7
commit
c0d4efed2e
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -9164,6 +9164,7 @@ tests/webtbs/tw13075.pp svneol=native#text/plain
|
|||||||
tests/webtbs/tw1310.pp svneol=native#text/plain
|
tests/webtbs/tw1310.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw13110.pp svneol=native#text/plain
|
tests/webtbs/tw13110.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw13133.pp svneol=native#text/plain
|
tests/webtbs/tw13133.pp svneol=native#text/plain
|
||||||
|
tests/webtbs/tw13135.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw1318.pp svneol=native#text/plain
|
tests/webtbs/tw1318.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw13186.pp svneol=native#text/plain
|
tests/webtbs/tw13186.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw13187.pp svneol=native#text/plain
|
tests/webtbs/tw13187.pp svneol=native#text/plain
|
||||||
|
@ -503,7 +503,7 @@ implementation
|
|||||||
{ Display info when multiple candidates are found }
|
{ Display info when multiple candidates are found }
|
||||||
candidates.dump_info(V_Debug);
|
candidates.dump_info(V_Debug);
|
||||||
{$endif EXTDEBUG}
|
{$endif EXTDEBUG}
|
||||||
cand_cnt:=candidates.choose_best(operpd,false);
|
cand_cnt:=candidates.choose_best(tabstractprocdef(operpd),false);
|
||||||
|
|
||||||
{ exit when no overloads are found }
|
{ exit when no overloads are found }
|
||||||
if cand_cnt=0 then
|
if cand_cnt=0 then
|
||||||
@ -649,7 +649,7 @@ implementation
|
|||||||
{ Display info when multiple candidates are found }
|
{ Display info when multiple candidates are found }
|
||||||
candidates.dump_info(V_Debug);
|
candidates.dump_info(V_Debug);
|
||||||
{$endif EXTDEBUG}
|
{$endif EXTDEBUG}
|
||||||
cand_cnt:=candidates.choose_best(operpd,false);
|
cand_cnt:=candidates.choose_best(tabstractprocdef(operpd),false);
|
||||||
|
|
||||||
{ exit when no overloads are found }
|
{ exit when no overloads are found }
|
||||||
if cand_cnt=0 then
|
if cand_cnt=0 then
|
||||||
@ -1519,16 +1519,8 @@ implementation
|
|||||||
{ if they are objects }
|
{ if they are objects }
|
||||||
if (def_from.typ=objectdef) and
|
if (def_from.typ=objectdef) and
|
||||||
(
|
(
|
||||||
(
|
|
||||||
not(m_delphi in current_settings.modeswitches) and
|
|
||||||
(tobjectdef(def_from).objecttype in [odt_object,odt_class]) and
|
|
||||||
(tobjectdef(def_to).objecttype in [odt_object,odt_class])
|
|
||||||
) or
|
|
||||||
(
|
|
||||||
(m_delphi in current_settings.modeswitches) and
|
|
||||||
(tobjectdef(def_from).objecttype=odt_object) and
|
(tobjectdef(def_from).objecttype=odt_object) and
|
||||||
(tobjectdef(def_to).objecttype=odt_object)
|
(tobjectdef(def_to).objecttype=odt_object)
|
||||||
)
|
|
||||||
) and
|
) and
|
||||||
(tobjectdef(def_from).is_related(tobjectdef(def_to))) then
|
(tobjectdef(def_from).is_related(tobjectdef(def_to))) then
|
||||||
eq:=te_convert_l1;
|
eq:=te_convert_l1;
|
||||||
|
@ -738,7 +738,7 @@ implementation
|
|||||||
{ release temp after next use }
|
{ release temp after next use }
|
||||||
addstatement(statements,ctempdeletenode.create_normal_temp(temp));
|
addstatement(statements,ctempdeletenode.create_normal_temp(temp));
|
||||||
addstatement(statements,ctemprefnode.create(temp));
|
addstatement(statements,ctemprefnode.create(temp));
|
||||||
typecheckpass(block);
|
typecheckpass(tnode(block));
|
||||||
left:=block;
|
left:=block;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2842,13 +2842,13 @@ implementation
|
|||||||
{ (simplify depends on typecheck info) }
|
{ (simplify depends on typecheck info) }
|
||||||
if assigned(callinitblock) then
|
if assigned(callinitblock) then
|
||||||
begin
|
begin
|
||||||
typecheckpass(callinitblock);
|
typecheckpass(tnode(callinitblock));
|
||||||
dosimplify(callinitblock);
|
dosimplify(tnode(callinitblock));
|
||||||
end;
|
end;
|
||||||
if assigned(callcleanupblock) then
|
if assigned(callcleanupblock) then
|
||||||
begin
|
begin
|
||||||
typecheckpass(callcleanupblock);
|
typecheckpass(tnode(callcleanupblock));
|
||||||
dosimplify(callcleanupblock);
|
dosimplify(tnode(callcleanupblock));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Continue with checking a normal call or generate the inlined code }
|
{ Continue with checking a normal call or generate the inlined code }
|
||||||
@ -2885,7 +2885,7 @@ implementation
|
|||||||
check_stack_parameters;
|
check_stack_parameters;
|
||||||
|
|
||||||
if assigned(callinitblock) then
|
if assigned(callinitblock) then
|
||||||
firstpass(callinitblock);
|
firstpass(tnode(callinitblock));
|
||||||
|
|
||||||
{ function result node (tempref or simple load) }
|
{ function result node (tempref or simple load) }
|
||||||
if assigned(funcretnode) then
|
if assigned(funcretnode) then
|
||||||
@ -2904,7 +2904,7 @@ implementation
|
|||||||
firstpass(methodpointer);
|
firstpass(methodpointer);
|
||||||
|
|
||||||
if assigned(callcleanupblock) then
|
if assigned(callcleanupblock) then
|
||||||
firstpass(callcleanupblock);
|
firstpass(tnode(callcleanupblock));
|
||||||
|
|
||||||
if not (block_type in [bt_const,bt_type,bt_const_type,bt_var_type]) then
|
if not (block_type in [bt_const,bt_type,bt_const_type,bt_var_type]) then
|
||||||
include(current_procinfo.flags,pi_do_call);
|
include(current_procinfo.flags,pi_do_call);
|
||||||
@ -3358,9 +3358,9 @@ implementation
|
|||||||
{ consider it must not be inlined if called
|
{ consider it must not be inlined if called
|
||||||
again inside the args or itself }
|
again inside the args or itself }
|
||||||
exclude(procdefinition.procoptions,po_inline);
|
exclude(procdefinition.procoptions,po_inline);
|
||||||
typecheckpass(inlineblock);
|
typecheckpass(tnode(inlineblock));
|
||||||
dosimplify(inlineblock);
|
dosimplify(tnode(inlineblock));
|
||||||
firstpass(inlineblock);
|
firstpass(tnode(inlineblock));
|
||||||
include(procdefinition.procoptions,po_inline);
|
include(procdefinition.procoptions,po_inline);
|
||||||
result:=inlineblock;
|
result:=inlineblock;
|
||||||
|
|
||||||
|
@ -935,7 +935,7 @@ implementation
|
|||||||
internalerror(200305264);
|
internalerror(200305264);
|
||||||
|
|
||||||
if assigned(callinitblock) then
|
if assigned(callinitblock) then
|
||||||
secondpass(callinitblock);
|
secondpass(tnode(callinitblock));
|
||||||
|
|
||||||
regs_to_save_int:=paramanager.get_volatile_registers_int(procdefinition.proccalloption);
|
regs_to_save_int:=paramanager.get_volatile_registers_int(procdefinition.proccalloption);
|
||||||
regs_to_save_fpu:=paramanager.get_volatile_registers_fpu(procdefinition.proccalloption);
|
regs_to_save_fpu:=paramanager.get_volatile_registers_fpu(procdefinition.proccalloption);
|
||||||
@ -1203,7 +1203,7 @@ implementation
|
|||||||
|
|
||||||
{ convert persistent temps for parameters and function result to normal temps }
|
{ convert persistent temps for parameters and function result to normal temps }
|
||||||
if assigned(callcleanupblock) then
|
if assigned(callcleanupblock) then
|
||||||
secondpass(callcleanupblock);
|
secondpass(tnode(callcleanupblock));
|
||||||
|
|
||||||
{ release temps and finalize unused return values, must be
|
{ release temps and finalize unused return values, must be
|
||||||
after the callcleanupblock because that converts temps
|
after the callcleanupblock because that converts temps
|
||||||
|
@ -1062,9 +1062,9 @@ implementation
|
|||||||
left := nil;
|
left := nil;
|
||||||
|
|
||||||
if is_typed then
|
if is_typed then
|
||||||
found_error:=handle_typed_read_write(filepara,Ttertiarynode(params),newstatement)
|
found_error:=handle_typed_read_write(filepara,Ttertiarynode(params),tnode(newstatement))
|
||||||
else
|
else
|
||||||
found_error:=handle_text_read_write(filepara,Ttertiarynode(params),newstatement);
|
found_error:=handle_text_read_write(filepara,Ttertiarynode(params),tnode(newstatement));
|
||||||
|
|
||||||
{ if we found an error, simply delete the generated blocknode }
|
{ if we found an error, simply delete the generated blocknode }
|
||||||
if found_error then
|
if found_error then
|
||||||
@ -2647,7 +2647,7 @@ implementation
|
|||||||
if assigned(tempnode) then
|
if assigned(tempnode) then
|
||||||
addstatement(newstatement,ctempdeletenode.create(tempnode));
|
addstatement(newstatement,ctempdeletenode.create(tempnode));
|
||||||
{ firstpass it }
|
{ firstpass it }
|
||||||
firstpass(newblock);
|
firstpass(tnode(newblock));
|
||||||
{ return new node }
|
{ return new node }
|
||||||
result := newblock;
|
result := newblock;
|
||||||
end;
|
end;
|
||||||
|
@ -115,10 +115,10 @@ implementation
|
|||||||
end;
|
end;
|
||||||
calln:
|
calln:
|
||||||
begin
|
begin
|
||||||
result := foreachnode(procmethod,tcallnode(n).callinitblock,f,arg) or result;
|
result := foreachnode(procmethod,tnode(tcallnode(n).callinitblock),f,arg) or result;
|
||||||
result := foreachnode(procmethod,tcallnode(n).methodpointer,f,arg) or result;
|
result := foreachnode(procmethod,tcallnode(n).methodpointer,f,arg) or result;
|
||||||
result := foreachnode(procmethod,tcallnode(n).funcretnode,f,arg) or result;
|
result := foreachnode(procmethod,tcallnode(n).funcretnode,f,arg) or result;
|
||||||
result := foreachnode(procmethod,tcallnode(n).callcleanupblock,f,arg) or result;
|
result := foreachnode(procmethod,tnode(tcallnode(n).callcleanupblock),f,arg) or result;
|
||||||
end;
|
end;
|
||||||
ifn, whilerepeatn, forn, tryexceptn, tryfinallyn:
|
ifn, whilerepeatn, forn, tryexceptn, tryfinallyn:
|
||||||
begin
|
begin
|
||||||
@ -194,10 +194,10 @@ implementation
|
|||||||
end;
|
end;
|
||||||
calln:
|
calln:
|
||||||
begin
|
begin
|
||||||
result := foreachnodestatic(procmethod,tcallnode(n).callinitblock,f,arg) or result;
|
result := foreachnodestatic(procmethod,tnode(tcallnode(n).callinitblock),f,arg) or result;
|
||||||
result := foreachnodestatic(procmethod,tcallnode(n).methodpointer,f,arg) or result;
|
result := foreachnodestatic(procmethod,tcallnode(n).methodpointer,f,arg) or result;
|
||||||
result := foreachnodestatic(procmethod,tcallnode(n).funcretnode,f,arg) or result;
|
result := foreachnodestatic(procmethod,tcallnode(n).funcretnode,f,arg) or result;
|
||||||
result := foreachnodestatic(procmethod,tcallnode(n).callcleanupblock,f,arg) or result;
|
result := foreachnodestatic(procmethod,tnode(tcallnode(n).callcleanupblock),f,arg) or result;
|
||||||
end;
|
end;
|
||||||
ifn, whilerepeatn, forn, tryexceptn, tryfinallyn:
|
ifn, whilerepeatn, forn, tryexceptn, tryfinallyn:
|
||||||
begin
|
begin
|
||||||
|
@ -416,9 +416,9 @@ unit optloop;
|
|||||||
{ clue everything together }
|
{ clue everything together }
|
||||||
if assigned(initcode) then
|
if assigned(initcode) then
|
||||||
begin
|
begin
|
||||||
do_firstpass(initcode);
|
do_firstpass(tnode(initcode));
|
||||||
do_firstpass(calccode);
|
do_firstpass(tnode(calccode));
|
||||||
do_firstpass(deletecode);
|
do_firstpass(tnode(deletecode));
|
||||||
{ create a new for node, the old one will be released by the compiler }
|
{ create a new for node, the old one will be released by the compiler }
|
||||||
with tfornode(node) do
|
with tfornode(node) do
|
||||||
begin
|
begin
|
||||||
|
@ -544,7 +544,7 @@ implementation
|
|||||||
hdef:=tpointerdef.create(p.resultdef);
|
hdef:=tpointerdef.create(p.resultdef);
|
||||||
{ load address of the value in a temp }
|
{ load address of the value in a temp }
|
||||||
tempnode:=ctempcreatenode.create_withnode(hdef,sizeof(pint),tt_persistent,true,p);
|
tempnode:=ctempcreatenode.create_withnode(hdef,sizeof(pint),tt_persistent,true,p);
|
||||||
typecheckpass(tempnode);
|
typecheckpass(tnode(tempnode));
|
||||||
valuenode:=p;
|
valuenode:=p;
|
||||||
refnode:=ctemprefnode.create(tempnode);
|
refnode:=ctemprefnode.create(tempnode);
|
||||||
fillchar(refnode.fileinfo,sizeof(tfileposinfo),0);
|
fillchar(refnode.fileinfo,sizeof(tfileposinfo),0);
|
||||||
|
@ -616,7 +616,7 @@ implementation
|
|||||||
addstatement(newstatement,bodyexitcode);
|
addstatement(newstatement,bodyexitcode);
|
||||||
addstatement(newstatement,final_asmnode);
|
addstatement(newstatement,final_asmnode);
|
||||||
end;
|
end;
|
||||||
do_firstpass(newblock);
|
do_firstpass(tnode(newblock));
|
||||||
code:=newblock;
|
code:=newblock;
|
||||||
current_filepos:=oldfilepos;
|
current_filepos:=oldfilepos;
|
||||||
end;
|
end;
|
||||||
|
@ -178,9 +178,9 @@ end;
|
|||||||
Procedure TProcess.FreeStreams;
|
Procedure TProcess.FreeStreams;
|
||||||
begin
|
begin
|
||||||
If FStderrStream<>FOutputStream then
|
If FStderrStream<>FOutputStream then
|
||||||
FreeStream(FStderrStream);
|
FreeStream(THandleStream(FStderrStream));
|
||||||
FreeStream(FOutputStream);
|
FreeStream(THandleStream(FOutputStream));
|
||||||
FreeStream(FInputStream);
|
FreeStream(THandleStream(FInputStream));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -221,17 +221,17 @@ end;
|
|||||||
|
|
||||||
procedure TProcess.CloseInput;
|
procedure TProcess.CloseInput;
|
||||||
begin
|
begin
|
||||||
FreeStream(FInputStream);
|
FreeStream(THandleStream(FInputStream));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TProcess.CloseOutput;
|
procedure TProcess.CloseOutput;
|
||||||
begin
|
begin
|
||||||
FreeStream(FOutputStream);
|
FreeStream(THandleStream(FOutputStream));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TProcess.CloseStderr;
|
procedure TProcess.CloseStderr;
|
||||||
begin
|
begin
|
||||||
FreeStream(FStderrStream);
|
FreeStream(THandleStream(FStderrStream));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Procedure TProcess.SetWindowColumns (Value : Cardinal);
|
Procedure TProcess.SetWindowColumns (Value : Cardinal);
|
||||||
|
22
tests/webtbs/tw13135.pp
Normal file
22
tests/webtbs/tw13135.pp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{ %fail }
|
||||||
|
{$mode objfpc}
|
||||||
|
|
||||||
|
type
|
||||||
|
ta = class
|
||||||
|
end;
|
||||||
|
|
||||||
|
tb = class(ta)
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure test(var a: ta);
|
||||||
|
begin
|
||||||
|
a.free;
|
||||||
|
a:=ta.create;
|
||||||
|
// now b contains an instance of type "ta"
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
b: tb;
|
||||||
|
begin
|
||||||
|
test(b);
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user