mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 18:25:58 +02:00
Merged revisions 13599-13600,13602-13604,13608,13615-13618 via svnmerge from
svn+ssh://jonas@svn.freepascal.org/FPC/svn/fpc/trunk git-svn-id: branches/objc@13621 -
This commit is contained in:
commit
5082e23d57
7
.gitattributes
vendored
7
.gitattributes
vendored
@ -8647,6 +8647,12 @@ tests/webtbf/tw1365.pp svneol=native#text/plain
|
|||||||
tests/webtbf/tw13815.pp svneol=native#text/plain
|
tests/webtbf/tw13815.pp svneol=native#text/plain
|
||||||
tests/webtbf/tw1395.pp svneol=native#text/plain
|
tests/webtbf/tw1395.pp svneol=native#text/plain
|
||||||
tests/webtbf/tw13956.pp svneol=native#text/plain
|
tests/webtbf/tw13956.pp svneol=native#text/plain
|
||||||
|
tests/webtbf/tw13971a.pp svneol=native#text/plain
|
||||||
|
tests/webtbf/tw13971b.pp svneol=native#text/plain
|
||||||
|
tests/webtbf/tw13971c.pp svneol=native#text/plain
|
||||||
|
tests/webtbf/tw13971d.pp svneol=native#text/plain
|
||||||
|
tests/webtbf/tw13971e.pp svneol=native#text/plain
|
||||||
|
tests/webtbf/tw13971f.pp svneol=native#text/plain
|
||||||
tests/webtbf/tw13992.pp svneol=native#text/plain
|
tests/webtbf/tw13992.pp svneol=native#text/plain
|
||||||
tests/webtbf/tw1407.pp svneol=native#text/plain
|
tests/webtbf/tw1407.pp svneol=native#text/plain
|
||||||
tests/webtbf/tw14104a.pp svneol=native#text/plain
|
tests/webtbf/tw14104a.pp svneol=native#text/plain
|
||||||
@ -9245,6 +9251,7 @@ tests/webtbs/tw14307.pp svneol=native#text/plain
|
|||||||
tests/webtbs/tw1433.pp svneol=native#text/plain
|
tests/webtbs/tw1433.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw14363.pp svneol=native#text/plain
|
tests/webtbs/tw14363.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw14403.pp svneol=native#text/plain
|
tests/webtbs/tw14403.pp svneol=native#text/plain
|
||||||
|
tests/webtbs/tw14418.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw1445.pp svneol=native#text/plain
|
tests/webtbs/tw1445.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw1450.pp svneol=native#text/plain
|
tests/webtbs/tw1450.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw1451.pp svneol=native#text/plain
|
tests/webtbs/tw1451.pp svneol=native#text/plain
|
||||||
|
@ -612,8 +612,8 @@ implementation
|
|||||||
for i:=0 to _class.ImplementedInterfaces.count-1 do
|
for i:=0 to _class.ImplementedInterfaces.count-1 do
|
||||||
begin
|
begin
|
||||||
ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]);
|
ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]);
|
||||||
{ if it implements itself }
|
{ if it implements itself and if it's not implemented by delegation }
|
||||||
if ImplIntf.VtblImplIntf=ImplIntf then
|
if (ImplIntf.VtblImplIntf=ImplIntf) and (ImplIntf.IType=etStandard) then
|
||||||
begin
|
begin
|
||||||
{ allocate a pointer in the object memory }
|
{ allocate a pointer in the object memory }
|
||||||
with tObjectSymtable(_class.symtable) do
|
with tObjectSymtable(_class.symtable) do
|
||||||
@ -630,7 +630,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]);
|
ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]);
|
||||||
if ImplIntf.VtblImplIntf<>ImplIntf then
|
if ImplIntf.VtblImplIntf<>ImplIntf then
|
||||||
ImplIntf.Ioffset:=ImplIntf.VtblImplIntf.Ioffset;
|
ImplIntf.IOffset:=ImplIntf.VtblImplIntf.IOffset;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1211,9 +1211,9 @@ implementation
|
|||||||
current_asmdata.asmlists[al_globals].concat(Tai_const.Createname(intf_get_vtbl_name(AImplIntf.VtblImplIntf),0));
|
current_asmdata.asmlists[al_globals].concat(Tai_const.Createname(intf_get_vtbl_name(AImplIntf.VtblImplIntf),0));
|
||||||
{ IOffset field }
|
{ IOffset field }
|
||||||
case AImplIntf.VtblImplIntf.IType of
|
case AImplIntf.VtblImplIntf.IType of
|
||||||
|
etFieldValue,
|
||||||
etStandard:
|
etStandard:
|
||||||
current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(AImplIntf.VtblImplIntf.IOffset));
|
current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(AImplIntf.VtblImplIntf.IOffset));
|
||||||
etFieldValue,
|
|
||||||
etVirtualMethodResult,
|
etVirtualMethodResult,
|
||||||
etStaticMethodResult:
|
etStaticMethodResult:
|
||||||
current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(0));
|
current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(0));
|
||||||
|
@ -309,8 +309,12 @@ implementation
|
|||||||
begin
|
begin
|
||||||
if is_open_string(vardef) then
|
if is_open_string(vardef) then
|
||||||
MessagePos(fileinfo,parser_w_cdecl_no_openstring);
|
MessagePos(fileinfo,parser_w_cdecl_no_openstring);
|
||||||
if not (po_external in pd.procoptions) then
|
if not(po_external in pd.procoptions) and
|
||||||
MessagePos(fileinfo,parser_w_cdecl_has_no_high);
|
(pd.typ<>procvardef) then
|
||||||
|
if is_array_of_const(vardef) then
|
||||||
|
MessagePos(fileinfo,parser_e_varargs_need_cdecl_and_external)
|
||||||
|
else
|
||||||
|
MessagePos(fileinfo,parser_w_cdecl_has_no_high);
|
||||||
end;
|
end;
|
||||||
if (vardef.typ=formaldef) and (Tformaldef(vardef).typed) then
|
if (vardef.typ=formaldef) and (Tformaldef(vardef).typed) then
|
||||||
begin
|
begin
|
||||||
|
@ -740,6 +740,7 @@ implementation
|
|||||||
if found then
|
if found then
|
||||||
begin
|
begin
|
||||||
ImplIntf.ImplementsGetter:=p;
|
ImplIntf.ImplementsGetter:=p;
|
||||||
|
ImplIntf.VtblImplIntf:=ImplIntf;
|
||||||
case p.propaccesslist[palt_read].firstsym^.sym.typ of
|
case p.propaccesslist[palt_read].firstsym^.sym.typ of
|
||||||
procsym :
|
procsym :
|
||||||
begin
|
begin
|
||||||
@ -749,7 +750,11 @@ implementation
|
|||||||
ImplIntf.IType:=etStaticMethodResult;
|
ImplIntf.IType:=etStaticMethodResult;
|
||||||
end;
|
end;
|
||||||
fieldvarsym :
|
fieldvarsym :
|
||||||
ImplIntf.IType:=etFieldValue;
|
begin
|
||||||
|
ImplIntf.IType:=etFieldValue;
|
||||||
|
{ this must be done more sophisticated, here is also probably the wrong place }
|
||||||
|
ImplIntf.IOffset:=tfieldvarsym(p.propaccesslist[palt_read].firstsym^.sym).fieldoffset;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
internalerror(200802161);
|
internalerror(200802161);
|
||||||
end;
|
end;
|
||||||
|
@ -2094,7 +2094,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
result:=true;
|
result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tclassrefdef.reset;
|
procedure tclassrefdef.reset;
|
||||||
begin
|
begin
|
||||||
@ -4502,7 +4502,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
result:=false;
|
result:=false;
|
||||||
{ interfaces being implemented through delegation are not mergable (FK) }
|
{ interfaces being implemented through delegation are not mergable (FK) }
|
||||||
if (MergingIntf.IType<>etStandard) or not(assigned(ProcDefs)) then
|
if (IType<>etStandard) or (MergingIntf.IType<>etStandard) or not(assigned(ProcDefs)) then
|
||||||
exit;
|
exit;
|
||||||
weight:=0;
|
weight:=0;
|
||||||
{ empty interface is mergeable }
|
{ empty interface is mergeable }
|
||||||
|
@ -152,7 +152,19 @@ begin
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
|
{$ifndef cpu64bitaddr}
|
||||||
|
{ Set the size of the page at address zero to 64kb, so nothing
|
||||||
|
is loaded below that address. This avoids problems with the
|
||||||
|
strange Windows-compatible resource handling that assumes
|
||||||
|
that addresses below 64kb do not exist.
|
||||||
|
|
||||||
|
On 64bit systems, page zero is 4GB by default, so no problems
|
||||||
|
there.
|
||||||
|
}
|
||||||
|
ExeCmd[1]:='ld $PRTOBJ $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -pagezero_size 0x10000 -no_dead_strip_inits_and_terms -multiply_defined suppress -L. -o $EXE `cat $RES`';
|
||||||
|
{$else ndef cpu64bitaddr}
|
||||||
ExeCmd[1]:='ld $PRTOBJ $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -no_dead_strip_inits_and_terms -multiply_defined suppress -L. -o $EXE `cat $RES`';
|
ExeCmd[1]:='ld $PRTOBJ $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -no_dead_strip_inits_and_terms -multiply_defined suppress -L. -o $EXE `cat $RES`';
|
||||||
|
{$endif ndef cpu64bitaddr}
|
||||||
if (apptype<>app_bundle) then
|
if (apptype<>app_bundle) then
|
||||||
DllCmd[1]:='libtool $PRTOBJ $OPT -no_dead_strip_inits_and_terms -dynamic -multiply_defined suppress -L. -o $EXE `cat $RES`'
|
DllCmd[1]:='libtool $PRTOBJ $OPT -no_dead_strip_inits_and_terms -dynamic -multiply_defined suppress -L. -o $EXE `cat $RES`'
|
||||||
else
|
else
|
||||||
|
@ -76,7 +76,7 @@ end;
|
|||||||
Constructor TChmWrapper.Create(name:string);
|
Constructor TChmWrapper.Create(name:string);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
ffs:=Classes.TFileStream.create(name,fmOpenRead);
|
ffs:=Classes.TFileStream.create(name,fmOpenRead or fmsharedenynone);
|
||||||
fchmr:=TChmReader.Create(ffs,True); // owns ffs
|
fchmr:=TChmReader.Create(ffs,True); // owns ffs
|
||||||
findex:=nil;
|
findex:=nil;
|
||||||
if not fchmr.isvalidfile then
|
if not fchmr.isvalidfile then
|
||||||
@ -235,8 +235,10 @@ begin
|
|||||||
freeandnil(ftopic);
|
freeandnil(ftopic);
|
||||||
freeandnil(findex);
|
freeandnil(findex);
|
||||||
freeandnil(fchmr);
|
freeandnil(fchmr);
|
||||||
|
{$ifdef wdebug}
|
||||||
|
debugmessageS({$i %file%},'TCHMWrapper: destroying ',{$i %line%},'1',0,0);
|
||||||
|
{$endif}
|
||||||
|
|
||||||
end;
|
end;
|
||||||
// m:=r.getobject(r.indexfile);
|
|
||||||
// siteindex.loadfromStream(m);
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -3217,7 +3217,7 @@ begin
|
|||||||
if Pointer(FCurrBlock) = Pointer(FCurrExtent) + sizeof(TExtent) then
|
if Pointer(FCurrBlock) = Pointer(FCurrExtent) + sizeof(TExtent) then
|
||||||
AddExtent(FCurrExtentSize * 2);
|
AddExtent(FCurrExtentSize * 2);
|
||||||
Result := FCurrBlock;
|
Result := FCurrBlock;
|
||||||
Dec(PChar(FCurrBlock), FElementSize);
|
Dec(PAnsiChar(FCurrBlock), FElementSize);
|
||||||
end;
|
end;
|
||||||
AClass.InitInstance(Result);
|
AClass.InitInstance(Result);
|
||||||
Result.FPool := Self; // mark as used
|
Result.FPool := Self; // mark as used
|
||||||
|
@ -55,7 +55,7 @@ type
|
|||||||
FBucketCount: LongWord;
|
FBucketCount: LongWord;
|
||||||
FBucket: PPHashItem;
|
FBucket: PPHashItem;
|
||||||
FOwnsObjects: Boolean;
|
FOwnsObjects: Boolean;
|
||||||
function Lookup(Key: PWideChar; KeyLength: Integer; var Found: Boolean; CanCreate: Boolean): PHashItem;
|
function Lookup(Key: PWideChar; KeyLength: Integer; out Found: Boolean; CanCreate: Boolean): PHashItem;
|
||||||
procedure Resize(NewCapacity: LongWord);
|
procedure Resize(NewCapacity: LongWord);
|
||||||
public
|
public
|
||||||
constructor Create(InitSize: Integer; OwnObjects: Boolean);
|
constructor Create(InitSize: Integer; OwnObjects: Boolean);
|
||||||
@ -73,7 +73,6 @@ type
|
|||||||
|
|
||||||
{ another hash, for detecting duplicate namespaced attributes without memory allocations }
|
{ another hash, for detecting duplicate namespaced attributes without memory allocations }
|
||||||
|
|
||||||
PWideString = ^WideString;
|
|
||||||
PExpHashEntry = ^TExpHashEntry;
|
PExpHashEntry = ^TExpHashEntry;
|
||||||
TExpHashEntry = record
|
TExpHashEntry = record
|
||||||
rev: LongWord;
|
rev: LongWord;
|
||||||
@ -129,7 +128,7 @@ begin
|
|||||||
Result := Xml11Pg;
|
Result := Xml11Pg;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function IsXml11Char(Value: PWideChar; var Index: Integer): Boolean; overload;
|
function IsXml11Char(Value: PWideChar; var Index: Integer): Boolean;
|
||||||
begin
|
begin
|
||||||
if (Value[Index] >= #$D800) and (Value[Index] <= #$DB7F) then
|
if (Value[Index] >= #$D800) and (Value[Index] <= #$DB7F) then
|
||||||
begin
|
begin
|
||||||
@ -140,7 +139,7 @@ begin
|
|||||||
Result := False;
|
Result := False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function IsXml11Char(const Value: WideString; var Index: Integer): Boolean; overload;
|
function IsXml11Char(const Value: WideString; var Index: Integer): Boolean;
|
||||||
begin
|
begin
|
||||||
if (Value[Index] >= #$D800) and (Value[Index] <= #$DB7F) then
|
if (Value[Index] >= #$D800) and (Value[Index] <= #$DB7F) then
|
||||||
begin
|
begin
|
||||||
@ -156,7 +155,7 @@ begin
|
|||||||
Result := IsXmlName(PWideChar(Value), Length(Value), Xml11);
|
Result := IsXmlName(PWideChar(Value), Length(Value), Xml11);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function IsXmlName(Value: PWideChar; Len: Integer; Xml11: Boolean = False): Boolean; overload;
|
function IsXmlName(Value: PWideChar; Len: Integer; Xml11: Boolean = False): Boolean;
|
||||||
var
|
var
|
||||||
Pages: PByteArray;
|
Pages: PByteArray;
|
||||||
I: Integer;
|
I: Integer;
|
||||||
@ -424,7 +423,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function THashTable.Lookup(Key: PWideChar; KeyLength: Integer;
|
function THashTable.Lookup(Key: PWideChar; KeyLength: Integer;
|
||||||
var Found: Boolean; CanCreate: Boolean): PHashItem;
|
out Found: Boolean; CanCreate: Boolean): PHashItem;
|
||||||
var
|
var
|
||||||
Entry: PPHashItem;
|
Entry: PPHashItem;
|
||||||
h: LongWord;
|
h: LongWord;
|
||||||
|
@ -619,8 +619,8 @@
|
|||||||
end;
|
end;
|
||||||
etFieldValue:
|
etFieldValue:
|
||||||
begin
|
begin
|
||||||
//writeln('Doing etFieldValue cast of ', TObject(Instance).classname(), ' with offset = ', IEntry^.IOffset);
|
// writeln('Doing etFieldValue cast of ', TObject(Instance).classname(), ' with offset = ', IEntry^.IOffset);
|
||||||
Pointer(obj) := ppointer(Pbyte(Instance)+IEntry^.IOffset)^;
|
Pointer(obj) := PPointer(Pbyte(Instance)+IEntry^.IOffset)^;
|
||||||
end;
|
end;
|
||||||
etVirtualMethodResult:
|
etVirtualMethodResult:
|
||||||
begin
|
begin
|
||||||
|
@ -72,8 +72,8 @@ CONST
|
|||||||
const
|
const
|
||||||
threadvarblocksize : dword = 0;
|
threadvarblocksize : dword = 0;
|
||||||
|
|
||||||
var
|
const
|
||||||
TLSKey : Dword;
|
TLSKey : DWord = $ffffffff;
|
||||||
|
|
||||||
procedure SysInitThreadvar(var offset : dword;size : dword);
|
procedure SysInitThreadvar(var offset : dword;size : dword);
|
||||||
begin
|
begin
|
||||||
@ -104,16 +104,17 @@ CONST
|
|||||||
var
|
var
|
||||||
dataindex : pointer;
|
dataindex : pointer;
|
||||||
errorsave : dword;
|
errorsave : dword;
|
||||||
begin
|
begin
|
||||||
{$ifdef win32}
|
{$ifdef dummy}
|
||||||
|
{ it least in the on windows 7 x64, this still doesn't not work, fs:(0x2c) is
|
||||||
|
self referencing on this system (FK) }
|
||||||
asm
|
asm
|
||||||
movl TLSKey,%edx
|
movl TLSKey,%edx
|
||||||
movl $0x2c,%eax
|
movl %fs:(0x2c),%eax
|
||||||
movl %fs:(%eax),%eax
|
|
||||||
orl %eax,%eax
|
orl %eax,%eax
|
||||||
jnz .LAddressInEAX
|
jnz .LAddressInEAX
|
||||||
movl $0x18,%eax
|
{ this works on Windows 7, but I don't know if it works on other OSes (FK) }
|
||||||
movl %fs:(%eax),%eax
|
movl %fs:(0x18),%eax
|
||||||
movl 0xe10(%eax,%edx,4),%eax
|
movl 0xe10(%eax,%edx,4),%eax
|
||||||
jmp .LToDataIndex
|
jmp .LToDataIndex
|
||||||
.LAddressInEAX:
|
.LAddressInEAX:
|
||||||
@ -186,11 +187,12 @@ CONST
|
|||||||
procedure SysInitMultithreading;
|
procedure SysInitMultithreading;
|
||||||
begin
|
begin
|
||||||
{ do not check IsMultiThread, as program could have altered it, out of Delphi habit }
|
{ do not check IsMultiThread, as program could have altered it, out of Delphi habit }
|
||||||
if TLSKey = 0 then
|
if TLSKey=$ffffffff then
|
||||||
begin
|
begin
|
||||||
{ We're still running in single thread mode, setup the TLS }
|
{ We're still running in single thread mode, setup the TLS }
|
||||||
TLSKey:=TlsAlloc;
|
TLSKey:=TlsAlloc;
|
||||||
InitThreadVars(@SysRelocateThreadvar);
|
InitThreadVars(@SysRelocateThreadvar);
|
||||||
|
{ allocate the thread vars for the main thread }
|
||||||
IsMultiThread:=true;
|
IsMultiThread:=true;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -200,7 +202,7 @@ CONST
|
|||||||
if IsMultiThread then
|
if IsMultiThread then
|
||||||
begin
|
begin
|
||||||
TlsFree(TLSKey);
|
TlsFree(TLSKey);
|
||||||
TLSKey := 0;
|
TLSKey:=$ffffffff;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
{ %fail }
|
||||||
|
|
||||||
{ first simple array of const test }
|
{ first simple array of const test }
|
||||||
|
|
||||||
|
19
tests/webtbf/tw13971a.pp
Normal file
19
tests/webtbf/tw13971a.pp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{ %fail }
|
||||||
|
|
||||||
|
{$ifdef fpc}
|
||||||
|
{$mode objfpc}
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
type
|
||||||
|
tc = class
|
||||||
|
function getx(i: longint): longint;
|
||||||
|
property prop[i: longint]: longint read getx;
|
||||||
|
default: longint;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function tc.getx(i: longint): longint;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
end.
|
19
tests/webtbf/tw13971b.pp
Normal file
19
tests/webtbf/tw13971b.pp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{ %fail }
|
||||||
|
|
||||||
|
{$ifdef fpc}
|
||||||
|
{$mode objfpc}
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
type
|
||||||
|
tc = class
|
||||||
|
constructor test;
|
||||||
|
a: longint;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor tc.test;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
end.
|
||||||
|
|
19
tests/webtbf/tw13971c.pp
Normal file
19
tests/webtbf/tw13971c.pp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{ %fail }
|
||||||
|
|
||||||
|
{$ifdef fpc}
|
||||||
|
{$mode objfpc}
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
type
|
||||||
|
tc = class
|
||||||
|
procedure test;
|
||||||
|
register: longint;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure tc.test;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
end.
|
||||||
|
|
18
tests/webtbf/tw13971d.pp
Normal file
18
tests/webtbf/tw13971d.pp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{ %fail }
|
||||||
|
|
||||||
|
{$ifdef fpc}
|
||||||
|
{$mode objfpc}
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
type
|
||||||
|
tc = class
|
||||||
|
function getx(i: longint): longint;
|
||||||
|
default: longint;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function tc.getx(i: longint): longint;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
end.
|
18
tests/webtbf/tw13971e.pp
Normal file
18
tests/webtbf/tw13971e.pp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{ %fail }
|
||||||
|
|
||||||
|
{$ifdef fpc}
|
||||||
|
{$mode objfpc}
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
type
|
||||||
|
tc = class
|
||||||
|
constructor create;
|
||||||
|
a: longint;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor tc.create;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
end.
|
18
tests/webtbf/tw13971f.pp
Normal file
18
tests/webtbf/tw13971f.pp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{ %fail }
|
||||||
|
|
||||||
|
{$ifdef fpc}
|
||||||
|
{$mode objfpc}
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
type
|
||||||
|
tc = class
|
||||||
|
destructor destroy; override;
|
||||||
|
a: longint;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor tc.destroy;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
end.
|
89
tests/webtbs/tw14418.pp
Normal file
89
tests/webtbs/tw14418.pp
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
program project1;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
uses
|
||||||
|
{$IFDEF UNIX}{$IFDEF UseCThreads}
|
||||||
|
cthreads,
|
||||||
|
{$ENDIF}{$ENDIF}
|
||||||
|
Classes
|
||||||
|
{ you can add units after this };
|
||||||
|
|
||||||
|
type
|
||||||
|
IIntf1 = interface
|
||||||
|
['{87776F0F-8CE0-4881-B969-C76F5A9CA517}']
|
||||||
|
procedure M1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
IIntf2 = interface
|
||||||
|
['{923C47DF-0A7E-4698-98B8-45175306CDF2}']
|
||||||
|
procedure M2;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TObjIntf2 }
|
||||||
|
|
||||||
|
TObjIntf2 = class(TInterfacedObject, IIntf2)
|
||||||
|
procedure M2;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TObj }
|
||||||
|
|
||||||
|
TObj = class(TInterfacedObject, IIntf1, IIntf2)
|
||||||
|
private
|
||||||
|
FObjIntf2:IIntf2;
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
|
||||||
|
procedure M1;
|
||||||
|
|
||||||
|
//when implementing IIntf2 using delegation,
|
||||||
|
//TObj1.M1 is called instead of TObjIntf2
|
||||||
|
property I2:IIntf2 read FObjIntf2 implements IIntf2;
|
||||||
|
|
||||||
|
//when implementing M2 directly it works right.
|
||||||
|
//procedure M2;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TObjIntf2 }
|
||||||
|
|
||||||
|
procedure TObjIntf2.M2;
|
||||||
|
begin
|
||||||
|
Writeln('TObjIntf2.M2 called');
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TObj }
|
||||||
|
|
||||||
|
constructor TObj.Create;
|
||||||
|
begin
|
||||||
|
FObjIntf2:=TObjIntf2.Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TObj.M1;
|
||||||
|
begin
|
||||||
|
Writeln('TObj.M1 called');
|
||||||
|
halt(1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{
|
||||||
|
procedure TObj.M2;
|
||||||
|
begin
|
||||||
|
Writeln('TObj.M2 called');
|
||||||
|
end;
|
||||||
|
}
|
||||||
|
|
||||||
|
var O:TObj;
|
||||||
|
i1:IIntf1;
|
||||||
|
i2:IIntf2;
|
||||||
|
begin
|
||||||
|
O:=TObj.Create;
|
||||||
|
i1:=O;
|
||||||
|
|
||||||
|
//all tries are unsuccessful
|
||||||
|
//i2:=O as IIntf2;
|
||||||
|
//(O as IIntf1).QueryInterface(IIntf2, i2);
|
||||||
|
i1.QueryInterface(IIntf2, i2);
|
||||||
|
|
||||||
|
//still calls TObj1.M1
|
||||||
|
i2.M2;
|
||||||
|
end.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user