mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 21:49:18 +02:00
* check for conflicts between procedure directives specified in the
implementation and "virtual" (if it's a virtual method), as "virtual" does not get repeated in the implementation and hence no conflicts get checked by default (mantis #32605) git-svn-id: trunk@37887 -
This commit is contained in:
parent
1b66995754
commit
672afcdca2
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -14310,6 +14310,7 @@ tests/webtbf/tw32412a.pp svneol=native#text/pascal
|
|||||||
tests/webtbf/tw32412b.pp svneol=native#text/pascal
|
tests/webtbf/tw32412b.pp svneol=native#text/pascal
|
||||||
tests/webtbf/tw32412c.pp svneol=native#text/pascal
|
tests/webtbf/tw32412c.pp svneol=native#text/pascal
|
||||||
tests/webtbf/tw3253.pp svneol=native#text/plain
|
tests/webtbf/tw3253.pp svneol=native#text/plain
|
||||||
|
tests/webtbf/tw32605.pp svneol=native#text/plain
|
||||||
tests/webtbf/tw3267.pp svneol=native#text/plain
|
tests/webtbf/tw3267.pp svneol=native#text/plain
|
||||||
tests/webtbf/tw3275.pp svneol=native#text/plain
|
tests/webtbf/tw3275.pp svneol=native#text/plain
|
||||||
tests/webtbf/tw3294.pp svneol=native#text/plain
|
tests/webtbf/tw3294.pp svneol=native#text/plain
|
||||||
|
@ -2871,18 +2871,25 @@ const
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function find_proc_directive_index(tok: ttoken): longint; inline;
|
||||||
|
begin
|
||||||
|
for result:=1 to num_proc_directives do
|
||||||
|
if proc_direcdata[result].idtok=tok then
|
||||||
|
exit;
|
||||||
|
result:=-1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function parse_proc_direc(pd:tabstractprocdef;var pdflags:tpdflags):boolean;
|
function parse_proc_direc(pd:tabstractprocdef;var pdflags:tpdflags):boolean;
|
||||||
{
|
{
|
||||||
Parse the procedure directive, returns true if a correct directive is found
|
Parse the procedure directive, returns true if a correct directive is found
|
||||||
}
|
}
|
||||||
var
|
var
|
||||||
p : longint;
|
p : longint;
|
||||||
found : boolean;
|
|
||||||
name : TIDString;
|
name : TIDString;
|
||||||
begin
|
begin
|
||||||
parse_proc_direc:=false;
|
parse_proc_direc:=false;
|
||||||
name:=tokeninfo^[idtoken].str;
|
name:=tokeninfo^[idtoken].str;
|
||||||
found:=false;
|
|
||||||
|
|
||||||
{ Hint directive? Then exit immediatly }
|
{ Hint directive? Then exit immediatly }
|
||||||
if (m_hintdirective in current_settings.modeswitches) then
|
if (m_hintdirective in current_settings.modeswitches) then
|
||||||
@ -2913,15 +2920,10 @@ const
|
|||||||
exit;
|
exit;
|
||||||
|
|
||||||
{ retrieve data for directive if found }
|
{ retrieve data for directive if found }
|
||||||
for p:=1 to num_proc_directives do
|
p:=find_proc_directive_index(idtoken);
|
||||||
if proc_direcdata[p].idtok=idtoken then
|
|
||||||
begin
|
|
||||||
found:=true;
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ Check if the procedure directive is known }
|
{ Check if the procedure directive is known }
|
||||||
if not found then
|
if p=-1 then
|
||||||
begin
|
begin
|
||||||
{ parsing a procvar type the name can be any
|
{ parsing a procvar type the name can be any
|
||||||
next variable !! }
|
next variable !! }
|
||||||
@ -3513,6 +3515,7 @@ const
|
|||||||
fwparacnt,
|
fwparacnt,
|
||||||
curridx,
|
curridx,
|
||||||
fwidx,
|
fwidx,
|
||||||
|
virtualdirinfo,
|
||||||
i : longint;
|
i : longint;
|
||||||
po_comp : tprocoptions;
|
po_comp : tprocoptions;
|
||||||
paracompopt: tcompare_paras_options;
|
paracompopt: tcompare_paras_options;
|
||||||
@ -3520,6 +3523,7 @@ const
|
|||||||
symentry: TSymEntry;
|
symentry: TSymEntry;
|
||||||
item : tlinkedlistitem;
|
item : tlinkedlistitem;
|
||||||
begin
|
begin
|
||||||
|
virtualdirinfo:=-1;
|
||||||
forwardfound:=false;
|
forwardfound:=false;
|
||||||
|
|
||||||
{ check overloaded functions if the same function already exists }
|
{ check overloaded functions if the same function already exists }
|
||||||
@ -3697,6 +3701,20 @@ const
|
|||||||
if (po_external in fwpd.procoptions) then
|
if (po_external in fwpd.procoptions) then
|
||||||
MessagePos(currpd.fileinfo,parser_e_proc_already_external);
|
MessagePos(currpd.fileinfo,parser_e_proc_already_external);
|
||||||
|
|
||||||
|
{ check for conflicts with "virtual" if this is a virtual
|
||||||
|
method, as "virtual" cannot be repeated in the
|
||||||
|
implementation and hence does not get checked against }
|
||||||
|
if (po_virtualmethod in fwpd.procoptions) then
|
||||||
|
begin
|
||||||
|
if virtualdirinfo=-1 then
|
||||||
|
begin
|
||||||
|
virtualdirinfo:=find_proc_directive_index(_VIRTUAL);
|
||||||
|
if virtualdirinfo=-1 then
|
||||||
|
internalerror(2018010101);
|
||||||
|
end;
|
||||||
|
if (proc_direcdata[virtualdirinfo].mutexclpo * currpd.procoptions)<>[] then
|
||||||
|
MessagePos1(currpd.fileinfo,parser_e_proc_dir_conflict,tokeninfo^[_VIRTUAL].str);
|
||||||
|
end;
|
||||||
{ Check parameters }
|
{ Check parameters }
|
||||||
if (m_repeat_forward in current_settings.modeswitches) or
|
if (m_repeat_forward in current_settings.modeswitches) or
|
||||||
(currpd.minparacount>0) then
|
(currpd.minparacount>0) then
|
||||||
|
39
tests/webtbf/tw32605.pp
Normal file
39
tests/webtbf/tw32605.pp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
{ %fail }
|
||||||
|
|
||||||
|
{$ifdef fpc}
|
||||||
|
{$mode delphi}
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
program InlineClass;
|
||||||
|
|
||||||
|
type
|
||||||
|
TAncestor = class
|
||||||
|
public
|
||||||
|
procedure TestMethod; virtual;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TDerived = class(TAncestor)
|
||||||
|
public
|
||||||
|
procedure TestMethod; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TAncestor.TestMethod; inline; // Virtual method with an 'inline' hint.
|
||||||
|
begin
|
||||||
|
WriteLn('Ancestor Method');
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDerived.TestMethod;
|
||||||
|
begin
|
||||||
|
WriteLn('Derived Method');
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
TestClass: TAncestor;
|
||||||
|
begin
|
||||||
|
TestClass := TDerived.Create;
|
||||||
|
try
|
||||||
|
TestClass.TestMethod; // <-- TAncestor.TestMethod is called instead of TDerived.TestMethod
|
||||||
|
finally
|
||||||
|
TestClass.Free;
|
||||||
|
end;
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user