diff --git a/.gitattributes b/.gitattributes index 630b8eebba..eebeeee392 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10862,6 +10862,7 @@ tests/webtbf/tw1928.pp svneol=native#text/plain tests/webtbf/tw1939.pp svneol=native#text/plain tests/webtbf/tw19463.pp svneol=native#text/pascal tests/webtbf/tw1949.pp svneol=native#text/plain +tests/webtbf/tw19591.pp svneol=native#text/plain tests/webtbf/tw1969.pp svneol=native#text/plain tests/webtbf/tw1995.pp svneol=native#text/plain tests/webtbf/tw2018.pp svneol=native#text/plain diff --git a/compiler/nobj.pas b/compiler/nobj.pas index b7d3a5ad91..7ce974f2f7 100644 --- a/compiler/nobj.pas +++ b/compiler/nobj.pas @@ -529,14 +529,19 @@ implementation begin { Find implementing procdef 1. Check for mapped name - 2. Use symbol name } + 2. Use symbol name, but only if there's no mapping, + or we're processing ancestor of interface. + When modifying this code, ensure that webtbs/tw11862, webtbs/tw4950 + and webtbf/tw19591 stay correct. } implprocdef:=nil; hs:=prefix+tprocdef(def).procsym.name; mappedname:=ImplIntf.GetMapping(hs); if mappedname<>'' then implprocdef:=intf_search_procdef_by_name(tprocdef(def),mappedname); if not assigned(implprocdef) then - implprocdef:=intf_search_procdef_by_name(tprocdef(def),tprocdef(def).procsym.name); + if (mappedname='') or (ImplIntf.IntfDef<>IntfDef) then + implprocdef:=intf_search_procdef_by_name(tprocdef(def),tprocdef(def).procsym.name); + { Add procdef to the implemented interface } if assigned(implprocdef) then begin diff --git a/tests/webtbf/tw19591.pp b/tests/webtbf/tw19591.pp new file mode 100644 index 0000000000..1b5de483e2 --- /dev/null +++ b/tests/webtbf/tw19591.pp @@ -0,0 +1,44 @@ +{ %fail } +{ %CPU=i386 } +{ %target=windows,linux } +{ Target must have distinct stdcall and cdecl calling conventions, otherwise this test will (wrongly) succeed } + +{$mode objfpc}{$H+} +{$MACRO ON} + +uses + Classes; + +type +// Declare wrong calling convention +{$ifdef WINDOWS} + {$DEFINE extdecl := cdecl} +{$else} + {$DEFINE extdecl := stdcall} +{$endif} + + { TObj } + + TObj = class(TInterfacedObject, IUnknown) + + function IUnknown._AddRef = AddRef; // This must produce a error because of calling convention mismatch. + + function AddRef : longint;extdecl; + end; + +{ TObj } + +function TObj.AddRef: longint;extdecl; +begin + WriteLn('TObj.AddRef call'); + inherited; +end; + +var O:TObj; + +begin + O:=TObj.Create; + (O as IUnknown)._AddRef; + O.Free; +end. +