mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 01:59:18 +02:00
fcl-passrc: added modeswitch OmitRTTI: treat class section published as public and typeinfo() does not work on symbols declared with this switch
git-svn-id: trunk@40342 -
This commit is contained in:
parent
cefb38b605
commit
1f061d0517
@ -1801,7 +1801,9 @@ type
|
|||||||
PosEl: TPasElement; RaiseIfConst: boolean = true): boolean;
|
PosEl: TPasElement; RaiseIfConst: boolean = true): boolean;
|
||||||
function ResolvedElIsClassInstance(const ResolvedEl: TPasResolverResult): boolean;
|
function ResolvedElIsClassInstance(const ResolvedEl: TPasResolverResult): boolean;
|
||||||
// utility functions
|
// utility functions
|
||||||
|
function ElHasModeSwitch(El: TPasElement; ms: TModeSwitch): boolean;
|
||||||
function GetElModeSwitches(El: TPasElement): TModeSwitches;
|
function GetElModeSwitches(El: TPasElement): TModeSwitches;
|
||||||
|
function ElHasBoolSwitch(El: TPasElement; bs: TBoolSwitch): boolean;
|
||||||
function GetElBoolSwitches(El: TPasElement): TBoolSwitches;
|
function GetElBoolSwitches(El: TPasElement): TBoolSwitches;
|
||||||
function GetProcTypeDescription(ProcType: TPasProcedureType;
|
function GetProcTypeDescription(ProcType: TPasProcedureType;
|
||||||
Flags: TPRProcTypeDescFlags = [prptdUseName,prptdResolveSimpleAlias]): string;
|
Flags: TPRProcTypeDescFlags = [prptdUseName,prptdResolveSimpleAlias]): string;
|
||||||
@ -8112,7 +8114,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
LTypeEl:=LeftResolved.LoTypeEl;
|
LTypeEl:=LeftResolved.LoTypeEl;
|
||||||
if (LTypeEl.ClassType=TPasPointerType)
|
if (LTypeEl.ClassType=TPasPointerType)
|
||||||
and (msAutoDeref in GetElModeSwitches(El))
|
and ElHasModeSwitch(El,msAutoDeref)
|
||||||
and (rrfReadable in LeftResolved.Flags)
|
and (rrfReadable in LeftResolved.Flags)
|
||||||
then
|
then
|
||||||
begin
|
begin
|
||||||
@ -8567,7 +8569,7 @@ procedure TPasResolver.ResolveArrayParamsArgs(Params: TParamsExpr;
|
|||||||
if not IsStringIndex then
|
if not IsStringIndex then
|
||||||
begin
|
begin
|
||||||
// pointer
|
// pointer
|
||||||
if not (bsPointerMath in GetElBoolSwitches(Params)) then
|
if not ElHasBoolSwitch(Params,bsPointerMath) then
|
||||||
exit(false);
|
exit(false);
|
||||||
end;
|
end;
|
||||||
Result:=true;
|
Result:=true;
|
||||||
@ -9624,7 +9626,7 @@ begin
|
|||||||
else if RightResolved.BaseType=btPointer then
|
else if RightResolved.BaseType=btPointer then
|
||||||
begin
|
begin
|
||||||
if (Bin.OpCode in [eopAdd,eopSubtract])
|
if (Bin.OpCode in [eopAdd,eopSubtract])
|
||||||
and (bsPointerMath in GetElBoolSwitches(Bin)) then
|
and ElHasBoolSwitch(Bin,bsPointerMath) then
|
||||||
begin
|
begin
|
||||||
// integer+CanonicalPointer
|
// integer+CanonicalPointer
|
||||||
SetResolverValueExpr(ResolvedEl,btPointer,
|
SetResolverValueExpr(ResolvedEl,btPointer,
|
||||||
@ -9638,7 +9640,7 @@ begin
|
|||||||
if RightTypeEl.ClassType=TPasPointerType then
|
if RightTypeEl.ClassType=TPasPointerType then
|
||||||
begin
|
begin
|
||||||
if (Bin.OpCode in [eopAdd,eopSubtract])
|
if (Bin.OpCode in [eopAdd,eopSubtract])
|
||||||
and (bsPointerMath in GetElBoolSwitches(Bin)) then
|
and ElHasBoolSwitch(Bin,bsPointerMath) then
|
||||||
begin
|
begin
|
||||||
// integer+TypedPointer
|
// integer+TypedPointer
|
||||||
RightTypeEl:=TPasPointerType(RightTypeEl).DestType;
|
RightTypeEl:=TPasPointerType(RightTypeEl).DestType;
|
||||||
@ -9837,7 +9839,7 @@ begin
|
|||||||
if (RightResolved.BaseType in btAllInteger) then
|
if (RightResolved.BaseType in btAllInteger) then
|
||||||
case Bin.OpCode of
|
case Bin.OpCode of
|
||||||
eopAdd,eopSubtract:
|
eopAdd,eopSubtract:
|
||||||
if bsPointerMath in GetElBoolSwitches(Bin) then
|
if ElHasBoolSwitch(Bin,bsPointerMath) then
|
||||||
begin
|
begin
|
||||||
// pointer+integer -> pointer
|
// pointer+integer -> pointer
|
||||||
SetResolverValueExpr(ResolvedEl,btPointer,
|
SetResolverValueExpr(ResolvedEl,btPointer,
|
||||||
@ -10118,7 +10120,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
if IsDynArray(LeftTypeEl)
|
if IsDynArray(LeftTypeEl)
|
||||||
and (Bin.OpCode=eopAdd)
|
and (Bin.OpCode=eopAdd)
|
||||||
and (msArrayOperators in GetElModeSwitches(Bin))
|
and ElHasModeSwitch(Bin,msArrayOperators)
|
||||||
and ((RightResolved.BaseType in [btArrayOrSet,btArrayLit])
|
and ((RightResolved.BaseType in [btArrayOrSet,btArrayLit])
|
||||||
or IsDynArray(RightResolved.LoTypeEl)) then
|
or IsDynArray(RightResolved.LoTypeEl)) then
|
||||||
begin
|
begin
|
||||||
@ -10131,7 +10133,7 @@ begin
|
|||||||
else if LeftTypeEl.ClassType=TPasPointerType then
|
else if LeftTypeEl.ClassType=TPasPointerType then
|
||||||
begin
|
begin
|
||||||
if (RightResolved.BaseType in btAllInteger)
|
if (RightResolved.BaseType in btAllInteger)
|
||||||
and (bsPointerMath in GetElBoolSwitches(Bin)) then
|
and ElHasBoolSwitch(Bin,bsPointerMath) then
|
||||||
begin
|
begin
|
||||||
// TypedPointer+Integer
|
// TypedPointer+Integer
|
||||||
SetLeftValueExpr([rrfReadable]);
|
SetLeftValueExpr([rrfReadable]);
|
||||||
@ -10226,7 +10228,7 @@ begin
|
|||||||
if (rrfReadable in LeftResolved.Flags)
|
if (rrfReadable in LeftResolved.Flags)
|
||||||
and (rrfReadable in RightResolved.Flags)
|
and (rrfReadable in RightResolved.Flags)
|
||||||
and (Bin.OpCode=eopAdd)
|
and (Bin.OpCode=eopAdd)
|
||||||
and (msArrayOperators in GetElModeSwitches(Bin)) then
|
and ElHasModeSwitch(Bin,msArrayOperators) then
|
||||||
begin
|
begin
|
||||||
if RightResolved.BaseType=btArrayLit then
|
if RightResolved.BaseType=btArrayLit then
|
||||||
begin
|
begin
|
||||||
@ -12581,14 +12583,14 @@ begin
|
|||||||
Result:=cExact
|
Result:=cExact
|
||||||
else if ParamResolved.BaseType=btPointer then
|
else if ParamResolved.BaseType=btPointer then
|
||||||
begin
|
begin
|
||||||
if bsPointerMath in GetElBoolSwitches(Expr) then
|
if ElHasBoolSwitch(Expr,bsPointerMath) then
|
||||||
Result:=cExact;
|
Result:=cExact;
|
||||||
end
|
end
|
||||||
else if ParamResolved.BaseType=btContext then
|
else if ParamResolved.BaseType=btContext then
|
||||||
begin
|
begin
|
||||||
TypeEl:=ParamResolved.LoTypeEl;
|
TypeEl:=ParamResolved.LoTypeEl;
|
||||||
if (TypeEl.ClassType=TPasPointerType)
|
if (TypeEl.ClassType=TPasPointerType)
|
||||||
and (bsPointerMath in GetElBoolSwitches(Expr)) then
|
and ElHasBoolSwitch(Expr,bsPointerMath) then
|
||||||
Result:=cExact;
|
Result:=cExact;
|
||||||
end;
|
end;
|
||||||
if Result=cIncompatible then
|
if Result=cIncompatible then
|
||||||
@ -17675,6 +17677,12 @@ begin
|
|||||||
exit(true);
|
exit(true);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TPasResolver.ElHasModeSwitch(El: TPasElement; ms: TModeSwitch
|
||||||
|
): boolean;
|
||||||
|
begin
|
||||||
|
Result:=ms in GetElModeSwitches(El);
|
||||||
|
end;
|
||||||
|
|
||||||
function TPasResolver.GetElModeSwitches(El: TPasElement): TModeSwitches;
|
function TPasResolver.GetElModeSwitches(El: TPasElement): TModeSwitches;
|
||||||
var
|
var
|
||||||
C: TClass;
|
C: TClass;
|
||||||
@ -17694,6 +17702,12 @@ begin
|
|||||||
Result:=CurrentParser.CurrentModeswitches;
|
Result:=CurrentParser.CurrentModeswitches;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TPasResolver.ElHasBoolSwitch(El: TPasElement; bs: TBoolSwitch
|
||||||
|
): boolean;
|
||||||
|
begin
|
||||||
|
Result:=bs in GetElBoolSwitches(El);
|
||||||
|
end;
|
||||||
|
|
||||||
function TPasResolver.GetElBoolSwitches(El: TPasElement): TBoolSwitches;
|
function TPasResolver.GetElBoolSwitches(El: TPasElement): TBoolSwitches;
|
||||||
var
|
var
|
||||||
C: TClass;
|
C: TClass;
|
||||||
@ -20280,7 +20294,7 @@ end;
|
|||||||
function TPasResolver.IsArrayOperatorAdd(Expr: TPasExpr): boolean;
|
function TPasResolver.IsArrayOperatorAdd(Expr: TPasExpr): boolean;
|
||||||
begin
|
begin
|
||||||
Result:=(Expr<>nil) and (Expr.ClassType=TBinaryExpr) and (Expr.OpCode=eopAdd)
|
Result:=(Expr<>nil) and (Expr.ClassType=TBinaryExpr) and (Expr.OpCode=eopAdd)
|
||||||
and (msArrayOperators in GetElModeSwitches(Expr));
|
and ElHasModeSwitch(Expr,msArrayOperators);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TPasResolver.IsTypeCast(Params: TParamsExpr): boolean;
|
function TPasResolver.IsTypeCast(Params: TParamsExpr): boolean;
|
||||||
@ -20603,8 +20617,14 @@ begin
|
|||||||
if El.CustomData is TResElDataBaseType then
|
if El.CustomData is TResElDataBaseType then
|
||||||
exit(true); // base type
|
exit(true); // base type
|
||||||
if El.Parent=nil then exit;
|
if El.Parent=nil then exit;
|
||||||
if (El.Parent is TPasType) and not HasTypeInfo(TPasType(El.Parent)) then
|
if El.Parent is TPasType then
|
||||||
exit;
|
begin
|
||||||
|
if not HasTypeInfo(TPasType(El.Parent)) then
|
||||||
|
exit;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if ElHasModeSwitch(El,msOmitRTTI) then
|
||||||
|
exit;
|
||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -6329,6 +6329,8 @@ begin
|
|||||||
Result:=isVisibility(S,AVisibility);
|
Result:=isVisibility(S,AVisibility);
|
||||||
if Result then
|
if Result then
|
||||||
begin
|
begin
|
||||||
|
if (AVisibility=visPublished) and (msOmitRTTI in Scanner.CurrentModeSwitches) then
|
||||||
|
AVisibility:=visPublic;
|
||||||
if B then
|
if B then
|
||||||
case AVisibility of
|
case AVisibility of
|
||||||
visPrivate : AVisibility:=visStrictPrivate;
|
visPrivate : AVisibility:=visStrictPrivate;
|
||||||
|
@ -284,7 +284,8 @@ type
|
|||||||
msArrayOperators, { use Delphi compatible array operators instead of custom ones ("+") }
|
msArrayOperators, { use Delphi compatible array operators instead of custom ones ("+") }
|
||||||
msExternalClass, { Allow external class definitions }
|
msExternalClass, { Allow external class definitions }
|
||||||
msPrefixedAttributes, { Allow attributes, disable proc modifier [] }
|
msPrefixedAttributes, { Allow attributes, disable proc modifier [] }
|
||||||
msIgnoreAttributes { workaround til resolver/converter supports attributes }
|
msIgnoreAttributes, { workaround til resolver/converter supports attributes }
|
||||||
|
msOmitRTTI { treat class section 'published' as 'public' and typeinfo does not work on symbols declared with this switch }
|
||||||
);
|
);
|
||||||
TModeSwitches = Set of TModeSwitch;
|
TModeSwitches = Set of TModeSwitch;
|
||||||
|
|
||||||
@ -1019,7 +1020,8 @@ const
|
|||||||
'ARRAYOPERATORS',
|
'ARRAYOPERATORS',
|
||||||
'EXTERNALCLASS',
|
'EXTERNALCLASS',
|
||||||
'PREFIXEDATTRIBUTES',
|
'PREFIXEDATTRIBUTES',
|
||||||
'IGNOREATTRIBUTES'
|
'IGNOREATTRIBUTES',
|
||||||
|
'OMITRTTI'
|
||||||
);
|
);
|
||||||
|
|
||||||
LetterSwitchNames: array['A'..'Z'] of string=(
|
LetterSwitchNames: array['A'..'Z'] of string=(
|
||||||
|
@ -315,6 +315,7 @@ type
|
|||||||
Procedure TestIncDec;
|
Procedure TestIncDec;
|
||||||
Procedure TestIncStringFail;
|
Procedure TestIncStringFail;
|
||||||
Procedure TestTypeInfo;
|
Procedure TestTypeInfo;
|
||||||
|
Procedure TestTypeInfo_FailRTTIDisabled;
|
||||||
|
|
||||||
// statements
|
// statements
|
||||||
Procedure TestForLoop;
|
Procedure TestForLoop;
|
||||||
@ -4707,6 +4708,21 @@ begin
|
|||||||
ParseProgram;
|
ParseProgram;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolver.TestTypeInfo_FailRTTIDisabled;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'{$modeswitch OmitRTTI}',
|
||||||
|
'type',
|
||||||
|
' TObject = class',
|
||||||
|
' end;',
|
||||||
|
'var o: TObject;',
|
||||||
|
'begin',
|
||||||
|
' if typeinfo(o)=nil then ;',
|
||||||
|
'']);
|
||||||
|
CheckResolverException(sSymbolCannotBePublished,nSymbolCannotBePublished);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestResolver.TestForLoop;
|
procedure TTestResolver.TestForLoop;
|
||||||
begin
|
begin
|
||||||
StartProgram(false);
|
StartProgram(false);
|
||||||
|
Loading…
Reference in New Issue
Block a user