mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-21 03:09:34 +02:00
* fix #40634: correctly check visibility for child classes in case of a mixture of specializations and non-specializations
+ added test
This commit is contained in:
parent
59d0af7f65
commit
d9903e6e16
@ -3264,6 +3264,8 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
|
orgcontextobjdef,
|
||||||
|
orgsymownerdef,
|
||||||
symownerdef : tabstractrecorddef;
|
symownerdef : tabstractrecorddef;
|
||||||
nonlocalst : tsymtable;
|
nonlocalst : tsymtable;
|
||||||
isspezproc : boolean;
|
isspezproc : boolean;
|
||||||
@ -3275,6 +3277,8 @@ implementation
|
|||||||
not (symst.symtabletype in [objectsymtable,recordsymtable]) then
|
not (symst.symtabletype in [objectsymtable,recordsymtable]) then
|
||||||
internalerror(200810285);
|
internalerror(200810285);
|
||||||
symownerdef:=tabstractrecorddef(symst.defowner);
|
symownerdef:=tabstractrecorddef(symst.defowner);
|
||||||
|
orgsymownerdef:=symownerdef;
|
||||||
|
orgcontextobjdef:=contextobjdef;
|
||||||
{ for specializations we need to check the visibility of the generic,
|
{ for specializations we need to check the visibility of the generic,
|
||||||
not the specialization (at least when comparing outside of the
|
not the specialization (at least when comparing outside of the
|
||||||
specialization }
|
specialization }
|
||||||
@ -3282,12 +3286,14 @@ implementation
|
|||||||
begin
|
begin
|
||||||
if not (symownerdef.genericdef.typ in [objectdef,recorddef]) then
|
if not (symownerdef.genericdef.typ in [objectdef,recorddef]) then
|
||||||
internalerror(2024020901);
|
internalerror(2024020901);
|
||||||
|
orgsymownerdef:=symownerdef;
|
||||||
symownerdef:=tabstractrecorddef(symownerdef.genericdef);
|
symownerdef:=tabstractrecorddef(symownerdef.genericdef);
|
||||||
end;
|
end;
|
||||||
if assigned(contextobjdef) and (df_specialization in contextobjdef.defoptions) then
|
if assigned(contextobjdef) and (df_specialization in contextobjdef.defoptions) then
|
||||||
begin
|
begin
|
||||||
if not (contextobjdef.genericdef.typ in [objectdef,recorddef]) then
|
if not (contextobjdef.genericdef.typ in [objectdef,recorddef]) then
|
||||||
internalerror(2024020902);
|
internalerror(2024020902);
|
||||||
|
orgcontextobjdef:=contextobjdef;
|
||||||
contextobjdef:=tabstractrecorddef(contextobjdef.genericdef);
|
contextobjdef:=tabstractrecorddef(contextobjdef.genericdef);
|
||||||
end;
|
end;
|
||||||
if assigned(current_structdef) and (df_specialization in current_structdef.defoptions) then
|
if assigned(current_structdef) and (df_specialization in current_structdef.defoptions) then
|
||||||
@ -3355,17 +3361,34 @@ implementation
|
|||||||
vis_strictprotected :
|
vis_strictprotected :
|
||||||
begin
|
begin
|
||||||
result:=(
|
result:=(
|
||||||
{ access from nested class }
|
{ access from nested class (specialization case) }
|
||||||
assigned(curstruct) and
|
assigned(curstruct) and
|
||||||
is_owned_by(curstruct,symownerdef)
|
is_owned_by(curstruct,symownerdef)
|
||||||
) or
|
) or
|
||||||
(
|
(
|
||||||
{ access from child class }
|
{ access from nested class (non-specialization case) }
|
||||||
|
(orgsymownerdef<>symownerdef) and
|
||||||
|
assigned(curstruct) and
|
||||||
|
is_owned_by(curstruct,orgsymownerdef)
|
||||||
|
) or
|
||||||
|
(
|
||||||
|
{ access from child class (specialization case) }
|
||||||
assigned(contextobjdef) and
|
assigned(contextobjdef) and
|
||||||
assigned(curstruct) and
|
assigned(curstruct) and
|
||||||
def_is_related(contextobjdef,symownerdef) and
|
def_is_related(contextobjdef,symownerdef) and
|
||||||
def_is_related(curstruct,contextobjdef)
|
def_is_related(curstruct,contextobjdef)
|
||||||
) or
|
) or
|
||||||
|
(
|
||||||
|
{ access from child class (non-specialization case) }
|
||||||
|
assigned(orgcontextobjdef) and
|
||||||
|
(
|
||||||
|
(orgcontextobjdef<>contextobjdef) or
|
||||||
|
(orgsymownerdef<>symownerdef)
|
||||||
|
) and
|
||||||
|
assigned(curstruct) and
|
||||||
|
def_is_related(orgcontextobjdef,orgsymownerdef) and
|
||||||
|
def_is_related(curstruct,orgcontextobjdef)
|
||||||
|
) or
|
||||||
(
|
(
|
||||||
{ helpers can access strict protected symbols }
|
{ helpers can access strict protected symbols }
|
||||||
is_objectpascal_helper(contextobjdef) and
|
is_objectpascal_helper(contextobjdef) and
|
||||||
@ -3389,11 +3412,25 @@ implementation
|
|||||||
is_current_unit(nonlocalst)
|
is_current_unit(nonlocalst)
|
||||||
) or
|
) or
|
||||||
(
|
(
|
||||||
|
{ context object is inside the current unit and related to
|
||||||
|
the symbol owner (specialization case) }
|
||||||
assigned(contextobjdef) and
|
assigned(contextobjdef) and
|
||||||
(contextobjdef.owner.symtabletype in [globalsymtable,staticsymtable,ObjectSymtable,recordsymtable,localsymtable]) and
|
(contextobjdef.owner.symtabletype in [globalsymtable,staticsymtable,ObjectSymtable,recordsymtable,localsymtable]) and
|
||||||
is_current_unit(contextobjdef.owner) and
|
is_current_unit(contextobjdef.owner) and
|
||||||
def_is_related(contextobjdef,symownerdef)
|
def_is_related(contextobjdef,symownerdef)
|
||||||
) or
|
) or
|
||||||
|
(
|
||||||
|
{ context object is inside the current unit and related to
|
||||||
|
the symbol owner (non-specialization case) }
|
||||||
|
assigned(orgcontextobjdef) and
|
||||||
|
(
|
||||||
|
(orgcontextobjdef<>contextobjdef) or
|
||||||
|
(orgsymownerdef<>symownerdef)
|
||||||
|
) and
|
||||||
|
(orgcontextobjdef.owner.symtabletype in [globalsymtable,staticsymtable,ObjectSymtable,recordsymtable,localsymtable]) and
|
||||||
|
is_current_unit(orgcontextobjdef.owner) and
|
||||||
|
def_is_related(orgcontextobjdef,orgsymownerdef)
|
||||||
|
) or
|
||||||
( // the case of specialize inside the generic declaration and nested types
|
( // the case of specialize inside the generic declaration and nested types
|
||||||
(nonlocalst.symtabletype in [objectsymtable,recordsymtable]) and
|
(nonlocalst.symtabletype in [objectsymtable,recordsymtable]) and
|
||||||
(
|
(
|
||||||
|
24
tests/webtbs/tw40634.pp
Normal file
24
tests/webtbs/tw40634.pp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{ %NORUN }
|
||||||
|
|
||||||
|
program tw40634;
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
uses uw40634a, uw40634b;
|
||||||
|
|
||||||
|
type
|
||||||
|
TWatchesSupplier = class(specialize TWatchesSupplierClassTemplate<TObject>, IDbgWatchesSupplierIntf)
|
||||||
|
//TWatchesSupplier = class(specialize TWatchesSupplierClassTemplate<TObject>)
|
||||||
|
//TWatchesSupplier = class(TNormalClass, IDbgWatchesSupplierIntf)
|
||||||
|
protected
|
||||||
|
procedure DoFoo;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TWatchesSupplier }
|
||||||
|
|
||||||
|
procedure TWatchesSupplier.DoFoo;
|
||||||
|
begin
|
||||||
|
if Monitor <> nil then;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
end.
|
||||||
|
|
80
tests/webtbs/uw40634a.pp
Normal file
80
tests/webtbs/uw40634a.pp
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
{***************************************************************************
|
||||||
|
* *
|
||||||
|
* This unit is distributed under the LGPL version 2 *
|
||||||
|
* *
|
||||||
|
* Additionally this unit can be used under any newer version (3 or up) *
|
||||||
|
* of the LGPL *
|
||||||
|
* *
|
||||||
|
* Users are also granted the same "linking exception" as defined *
|
||||||
|
* for the LCL. *
|
||||||
|
* See the LCL license for details *
|
||||||
|
* *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
@author(Martin Friebe)
|
||||||
|
}
|
||||||
|
unit uw40634a;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
{$INTERFACES CORBA} // no ref counting needed
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, uw40634b;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
TNormalClass = class
|
||||||
|
strict protected
|
||||||
|
procedure SetMonitor(AMonitor: IDbgWatchesMonitorIntf); virtual; abstract;
|
||||||
|
procedure RequestData(AWatchValue: IDbgWatchValueIntf); virtual; abstract;
|
||||||
|
function Monitor:TObject;virtual; abstract;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TInternalDbgSupplierBase }
|
||||||
|
|
||||||
|
generic TInternalDbgSupplierBase<
|
||||||
|
_BASE: TObject;
|
||||||
|
_SUPPLIER_INTF: IInternalDbgSupplierIntfType;
|
||||||
|
_MONITOR_INTF //: IInternalDbgMonitorIntfType
|
||||||
|
>
|
||||||
|
= class(_BASE)
|
||||||
|
strict private
|
||||||
|
FMonitor: _MONITOR_INTF;
|
||||||
|
|
||||||
|
|
||||||
|
// ********************************************************************************
|
||||||
|
(* "private" is CORRECTLY not working
|
||||||
|
all others should work, but have different error *)
|
||||||
|
|
||||||
|
//private
|
||||||
|
strict protected
|
||||||
|
procedure SetMonitor1(AMonitor: _MONITOR_INTF);virtual; abstract;
|
||||||
|
protected
|
||||||
|
procedure SetMonitor2(AMonitor: _MONITOR_INTF);virtual; abstract;
|
||||||
|
public
|
||||||
|
procedure SetMonitor3(AMonitor: _MONITOR_INTF);virtual; abstract;
|
||||||
|
// ********************************************************************************
|
||||||
|
protected
|
||||||
|
|
||||||
|
property Monitor: _MONITOR_INTF read FMonitor;
|
||||||
|
end;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
{ TWatchesSupplierClassTemplate }
|
||||||
|
|
||||||
|
generic TWatchesSupplierClassTemplate<_BASE: TObject> = class(
|
||||||
|
specialize TInternalDbgSupplierBase<_BASE, IDbgWatchesSupplierIntf, IDbgWatchesMonitorIntf>,
|
||||||
|
IDbgWatchesSupplierIntf
|
||||||
|
)
|
||||||
|
protected
|
||||||
|
public
|
||||||
|
procedure RequestData(AWatchValue: IDbgWatchValueIntf); virtual; abstract;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
end.
|
69
tests/webtbs/uw40634b.pp
Normal file
69
tests/webtbs/uw40634b.pp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
{***************************************************************************
|
||||||
|
* *
|
||||||
|
* This unit is distributed under the LGPL version 2 *
|
||||||
|
* *
|
||||||
|
* Additionally this unit can be used under any newer version (3 or up) *
|
||||||
|
* of the LGPL *
|
||||||
|
* *
|
||||||
|
* Users are also granted the same "linking exception" as defined *
|
||||||
|
* for the LCL. *
|
||||||
|
* See the LCL license for details *
|
||||||
|
* *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
@author(Martin Friebe)
|
||||||
|
}
|
||||||
|
unit uw40634b;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
{$INTERFACES CORBA} // no ref counting needed
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, Types;
|
||||||
|
|
||||||
|
type
|
||||||
|
TDBGState = integer;
|
||||||
|
IDbgWatchValueIntf = interface end;
|
||||||
|
IDbgWatchDataIntf = interface end;
|
||||||
|
|
||||||
|
{$REGION ***** Internal types ***** }
|
||||||
|
|
||||||
|
IInternalDbgMonitorIntfType = interface end;
|
||||||
|
IInternalDbgSupplierIntfType = interface end;
|
||||||
|
|
||||||
|
generic IInternalDbgMonitorIntf<_SUPPLIER_INTF> = interface(IInternalDbgMonitorIntfType)
|
||||||
|
procedure RemoveSupplier(ASupplier: _SUPPLIER_INTF);
|
||||||
|
end;
|
||||||
|
|
||||||
|
generic IInternalDbgSupplierIntf<_MONITOR_INTF> = interface(IInternalDbgSupplierIntfType)
|
||||||
|
procedure SetMonitor1(AMonitor: _MONITOR_INTF);
|
||||||
|
procedure SetMonitor2(AMonitor: _MONITOR_INTF);
|
||||||
|
procedure SetMonitor3(AMonitor: _MONITOR_INTF);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$ENDREGION}
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
IDbgWatchesSupplierIntf = interface;
|
||||||
|
|
||||||
|
IDbgWatchesMonitorIntf = interface(specialize IInternalDbgMonitorIntf<IDbgWatchesSupplierIntf>)
|
||||||
|
['{42A7069E-D5DD-4350-A592-2000F67DC7E9}']
|
||||||
|
procedure InvalidateWatchValues;
|
||||||
|
procedure DoStateChange(const AOldState, ANewState: TDBGState); //deprecated;
|
||||||
|
end;
|
||||||
|
|
||||||
|
IDbgWatchesSupplierIntf = interface(specialize IInternalDbgSupplierIntf<IDbgWatchesMonitorIntf>)
|
||||||
|
['{F893B607-C295-4A3A-8253-FAB3D03C5AD5}']
|
||||||
|
procedure RequestData(AWatchValue: IDbgWatchValueIntf);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user