mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 19:49:22 +02:00
* fix for Mantis #37251: apply patches by Bi0T1N to implement the IsConstValue() intrinsic
+ added tests git-svn-id: trunk@45695 -
This commit is contained in:
parent
533dc96db5
commit
d401639b24
4
.gitattributes
vendored
4
.gitattributes
vendored
@ -15121,6 +15121,10 @@ tests/test/tintfcdecl1.pp svneol=native#text/plain
|
|||||||
tests/test/tintfcdecl2.pp svneol=native#text/plain
|
tests/test/tintfcdecl2.pp svneol=native#text/plain
|
||||||
tests/test/tintfdef.pp svneol=native#text/plain
|
tests/test/tintfdef.pp svneol=native#text/plain
|
||||||
tests/test/tintuint.pp svneol=native#text/plain
|
tests/test/tintuint.pp svneol=native#text/plain
|
||||||
|
tests/test/tisconstvalue1.pp svneol=native#text/pascal
|
||||||
|
tests/test/tisconstvalue2.pp svneol=native#text/pascal
|
||||||
|
tests/test/tisconstvalue3.pp svneol=native#text/pascal
|
||||||
|
tests/test/tisconstvalue4.pp svneol=native#text/pascal
|
||||||
tests/test/tismngd1.pp svneol=native#text/pascal
|
tests/test/tismngd1.pp svneol=native#text/pascal
|
||||||
tests/test/tismngd2.pp svneol=native#text/pascal
|
tests/test/tismngd2.pp svneol=native#text/pascal
|
||||||
tests/test/tisobuf1.pp svneol=native#text/pascal
|
tests/test/tisobuf1.pp svneol=native#text/pascal
|
||||||
|
@ -163,12 +163,15 @@ type
|
|||||||
in_mmx_pcmpeqd = 202,
|
in_mmx_pcmpeqd = 202,
|
||||||
in_mmx_pcmpgtb = 203,
|
in_mmx_pcmpgtb = 203,
|
||||||
in_mmx_pcmpgtw = 204,
|
in_mmx_pcmpgtw = 204,
|
||||||
in_mmx_pcmpgtd = 205
|
in_mmx_pcmpgtd = 205,
|
||||||
|
|
||||||
{ 3DNow }
|
{ 3DNow }
|
||||||
|
|
||||||
{ SSE }
|
{ SSE }
|
||||||
|
|
||||||
|
{ More internal functions }
|
||||||
|
in_isconstvalue_x = 1000
|
||||||
|
|
||||||
{$if defined(X86)}
|
{$if defined(X86)}
|
||||||
,
|
,
|
||||||
{$i x86/cx86innr.inc}
|
{$i x86/cx86innr.inc}
|
||||||
|
@ -3169,6 +3169,12 @@ implementation
|
|||||||
resultdef:=pasbool1type;
|
resultdef:=pasbool1type;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
in_isconstvalue_x:
|
||||||
|
begin
|
||||||
|
set_varstate(left,vs_read,[vsf_must_be_valid]);
|
||||||
|
resultdef:=pasbool1type;
|
||||||
|
end;
|
||||||
|
|
||||||
in_assigned_x:
|
in_assigned_x:
|
||||||
begin
|
begin
|
||||||
{ the parser has already made sure the expression is valid }
|
{ the parser has already made sure the expression is valid }
|
||||||
@ -3863,6 +3869,14 @@ implementation
|
|||||||
result:=cordconstnode.create(0,resultdef,false);
|
result:=cordconstnode.create(0,resultdef,false);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
in_isconstvalue_x:
|
||||||
|
begin
|
||||||
|
if is_constnode(left) then
|
||||||
|
result:=cordconstnode.create(1,resultdef,false)
|
||||||
|
else
|
||||||
|
result:=cordconstnode.create(0,resultdef,false);
|
||||||
|
end;
|
||||||
|
|
||||||
in_assigned_x:
|
in_assigned_x:
|
||||||
begin
|
begin
|
||||||
result:=first_assigned;
|
result:=first_assigned;
|
||||||
|
@ -524,6 +524,16 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
in_isconstvalue_x:
|
||||||
|
begin
|
||||||
|
consume(_LKLAMMER);
|
||||||
|
in_args:=true;
|
||||||
|
p1:=comp_expr([ef_accept_equal]);
|
||||||
|
consume(_RKLAMMER);
|
||||||
|
p2:=geninlinenode(l,false,p1);
|
||||||
|
statement_syssym:=p2;
|
||||||
|
end;
|
||||||
|
|
||||||
in_aligned_x,
|
in_aligned_x,
|
||||||
in_unaligned_x,
|
in_unaligned_x,
|
||||||
in_volatile_x:
|
in_volatile_x:
|
||||||
|
@ -112,6 +112,7 @@ implementation
|
|||||||
systemunit.insert(csyssym.create('Delete',in_delete_x_y_z));
|
systemunit.insert(csyssym.create('Delete',in_delete_x_y_z));
|
||||||
systemunit.insert(csyssym.create('GetTypeKind',in_gettypekind_x));
|
systemunit.insert(csyssym.create('GetTypeKind',in_gettypekind_x));
|
||||||
systemunit.insert(csyssym.create('IsManagedType',in_ismanagedtype_x));
|
systemunit.insert(csyssym.create('IsManagedType',in_ismanagedtype_x));
|
||||||
|
systemunit.insert(csyssym.create('IsConstValue',in_isconstvalue_x));
|
||||||
systemunit.insert(csyssym.create('fpc_eh_return_data_regno', in_const_eh_return_data_regno));
|
systemunit.insert(csyssym.create('fpc_eh_return_data_regno', in_const_eh_return_data_regno));
|
||||||
systemunit.insert(cconstsym.create_ord('False',constord,0,pasbool1type));
|
systemunit.insert(cconstsym.create_ord('False',constord,0,pasbool1type));
|
||||||
systemunit.insert(cconstsym.create_ord('True',constord,1,pasbool1type));
|
systemunit.insert(cconstsym.create_ord('True',constord,1,pasbool1type));
|
||||||
|
148
tests/test/tisconstvalue1.pp
Normal file
148
tests/test/tisconstvalue1.pp
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
program tisconstvalue1;
|
||||||
|
|
||||||
|
{$mode objfpc}
|
||||||
|
{$modeswitch advancedrecords}
|
||||||
|
|
||||||
|
type
|
||||||
|
TTestLongInt = record
|
||||||
|
a: LongInt;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TTestAnsiString = record
|
||||||
|
a: AnsiString;
|
||||||
|
end;
|
||||||
|
{
|
||||||
|
TTestManaged = record
|
||||||
|
a: LongInt;
|
||||||
|
class operator Initialize(var aTestManaged: TTestManaged);
|
||||||
|
end;
|
||||||
|
|
||||||
|
class operator TTestManaged.Initialize(var aTestManaged: TTestManaged);
|
||||||
|
begin
|
||||||
|
aTestManaged.a := 42;
|
||||||
|
end;
|
||||||
|
}
|
||||||
|
type
|
||||||
|
TDynArrayLongInt = array of LongInt;
|
||||||
|
TStaticArrayAnsiString = array[0..4] of AnsiString;
|
||||||
|
|
||||||
|
TEnum = (eOne, eTwo, eThree);
|
||||||
|
TSet = set of (sOne, sTwo, sThree);
|
||||||
|
|
||||||
|
const
|
||||||
|
// untyped
|
||||||
|
Number = 100;
|
||||||
|
Str = 'Hello World!';
|
||||||
|
Dbl = 1.1;
|
||||||
|
NilPtr = nil;
|
||||||
|
IsConst = True;
|
||||||
|
GUID = '{10101010-1010-0101-1001-110110110110}';
|
||||||
|
// typed
|
||||||
|
IntConst: Integer = 13;
|
||||||
|
RealConst: Real = 12;
|
||||||
|
Alphabet: array [1..26] of char =
|
||||||
|
('A','B','C','D','E','F','G','H','I',
|
||||||
|
'J','K','L','M','N','O','P','Q','R',
|
||||||
|
'S','T','U','V','W','X','Y','Z');
|
||||||
|
MyGUID: TGUID = '{10101010-1010-0101-1001-110110110110}';
|
||||||
|
Bool: Boolean = False;
|
||||||
|
|
||||||
|
var
|
||||||
|
l: LongInt;
|
||||||
|
o: TObject;
|
||||||
|
_as: AnsiString;
|
||||||
|
lir: TTestLongInt;
|
||||||
|
asr: TTestAnsiString;
|
||||||
|
//mr: TTestManaged;
|
||||||
|
liarr: TDynArrayLongInt;
|
||||||
|
sasarr: TStaticArrayAnsiString;
|
||||||
|
|
||||||
|
begin
|
||||||
|
l := 1;
|
||||||
|
if IsConstValue(l) then
|
||||||
|
Halt(1);
|
||||||
|
|
||||||
|
o := TObject.Create;
|
||||||
|
try
|
||||||
|
if IsConstValue(o) then
|
||||||
|
Halt(2);
|
||||||
|
finally
|
||||||
|
o.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
_as := 'Hello World!';
|
||||||
|
if IsConstValue(_as) then
|
||||||
|
Halt(3);
|
||||||
|
|
||||||
|
if not IsConstValue(eOne) then
|
||||||
|
Halt(4);
|
||||||
|
if not IsConstValue(eTwo) then
|
||||||
|
Halt(5);
|
||||||
|
if not IsConstValue(eThree) then
|
||||||
|
Halt(6);
|
||||||
|
|
||||||
|
if not IsConstValue(Number) then
|
||||||
|
Halt(7);
|
||||||
|
if not IsConstValue(Str) then
|
||||||
|
Halt(8);
|
||||||
|
|
||||||
|
lir.a := 5;
|
||||||
|
if IsConstValue(lir) then
|
||||||
|
Halt(9);
|
||||||
|
|
||||||
|
asr.a := 'Hello World!';
|
||||||
|
if IsConstValue(asr) then
|
||||||
|
Halt(10);
|
||||||
|
{
|
||||||
|
if IsConstValue(mr) then
|
||||||
|
Halt(11);
|
||||||
|
}
|
||||||
|
SetLength(liarr, 2);
|
||||||
|
liarr[0] := 1;
|
||||||
|
liarr[1] := 2;
|
||||||
|
if IsConstValue(liarr) then
|
||||||
|
Halt(12);
|
||||||
|
|
||||||
|
sasarr[0] := 'Hell';
|
||||||
|
sasarr[1] := 'o ';
|
||||||
|
sasarr[2] := 'Wor';
|
||||||
|
sasarr[3] := 'ld!';
|
||||||
|
if IsConstValue(sasarr) then
|
||||||
|
Halt(13);
|
||||||
|
|
||||||
|
if not IsConstValue(sOne) then
|
||||||
|
Halt(14);
|
||||||
|
if not IsConstValue(sTwo) then
|
||||||
|
Halt(15);
|
||||||
|
if not IsConstValue(sThree) then
|
||||||
|
Halt(16);
|
||||||
|
|
||||||
|
if not IsConstValue(Dbl) then
|
||||||
|
Halt(17);
|
||||||
|
|
||||||
|
if not IsConstValue(NilPtr) then
|
||||||
|
Halt(18);
|
||||||
|
|
||||||
|
if not IsConstValue(IsConst) then
|
||||||
|
Halt(19);
|
||||||
|
|
||||||
|
if not IsConstValue(GUID) then
|
||||||
|
Halt(20);
|
||||||
|
|
||||||
|
if IsConstValue(IntConst) then
|
||||||
|
Halt(21);
|
||||||
|
|
||||||
|
if IsConstValue(RealConst) then
|
||||||
|
Halt(22);
|
||||||
|
|
||||||
|
if IsConstValue(Alphabet) then
|
||||||
|
Halt(23);
|
||||||
|
|
||||||
|
if IsConstValue(MyGUID) then
|
||||||
|
Halt(24);
|
||||||
|
|
||||||
|
if IsConstValue(Bool) then
|
||||||
|
Halt(25);
|
||||||
|
|
||||||
|
Writeln('Ok');
|
||||||
|
end.
|
62
tests/test/tisconstvalue2.pp
Normal file
62
tests/test/tisconstvalue2.pp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
program tisconstvalue2;
|
||||||
|
|
||||||
|
{$mode Delphi}
|
||||||
|
|
||||||
|
// example taken from https://stackoverflow.com/a/30417597
|
||||||
|
|
||||||
|
type
|
||||||
|
TFlavor = (Tasty, Nasty);
|
||||||
|
|
||||||
|
TIntegerHelper = record helper for Integer
|
||||||
|
private
|
||||||
|
function GetTastyPoint: Integer;
|
||||||
|
function GetNastyPoint: Integer;
|
||||||
|
public
|
||||||
|
function GetSomething(Flavor: TFlavor): Integer; inline;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TIntegerHelper.GetTastyPoint: Integer;
|
||||||
|
begin
|
||||||
|
Result := 10;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TIntegerHelper.GetNastyPoint: Integer;
|
||||||
|
begin
|
||||||
|
Result := -10;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TIntegerHelper.GetSomething(Flavor: TFlavor): Integer;
|
||||||
|
begin
|
||||||
|
if IsConstValue(Flavor) then
|
||||||
|
begin
|
||||||
|
if Flavor = Tasty then
|
||||||
|
Result := Self.GetTastyPoint
|
||||||
|
else
|
||||||
|
Result := Self.GetNastyPoint;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
n: TFlavor;
|
||||||
|
|
||||||
|
begin
|
||||||
|
i := 100000.GetSomething(Tasty);
|
||||||
|
if i <> 10 then
|
||||||
|
Halt(1);
|
||||||
|
|
||||||
|
n := Tasty;
|
||||||
|
i := 100000.GetSomething(Nasty);
|
||||||
|
if i <> -10 then
|
||||||
|
Halt(2);
|
||||||
|
|
||||||
|
i := 100000.GetSomething(n);
|
||||||
|
if i <> 0 then
|
||||||
|
Halt(3);
|
||||||
|
|
||||||
|
Writeln('Ok');
|
||||||
|
end.
|
131
tests/test/tisconstvalue3.pp
Normal file
131
tests/test/tisconstvalue3.pp
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
program tisconstvalue3;
|
||||||
|
|
||||||
|
{$IFDEF FPC}
|
||||||
|
{$mode Delphi}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
type
|
||||||
|
TMyClass = class
|
||||||
|
const
|
||||||
|
PI = 3.14;
|
||||||
|
private
|
||||||
|
FNumber: Integer;
|
||||||
|
public
|
||||||
|
function DoMathAndReturn(const AValue: Integer): Integer;
|
||||||
|
published
|
||||||
|
property MyNumber: Integer read FNumber;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TClassOf = class of TMyClass;
|
||||||
|
|
||||||
|
function TMyClass.DoMathAndReturn(const AValue: Integer): Integer;
|
||||||
|
begin
|
||||||
|
Result := FNumber * 2;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function WorldCopy(AInput: String): String;
|
||||||
|
begin
|
||||||
|
if IsConstValue(AInput) then
|
||||||
|
Halt(9);
|
||||||
|
|
||||||
|
Result := 'Hello ' + AInput;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function WorldConst(const AInput: String): String;
|
||||||
|
begin
|
||||||
|
if IsConstValue(AInput) then
|
||||||
|
Halt(10);
|
||||||
|
|
||||||
|
Result := 'Hello ' + AInput;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function WorldVar(var AInput: String): String;
|
||||||
|
begin
|
||||||
|
if IsConstValue(AInput) then
|
||||||
|
Halt(11);
|
||||||
|
|
||||||
|
Result := 'Hello ' + AInput;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function WorldOut(out AInput: String): String;
|
||||||
|
begin
|
||||||
|
AInput := 'Test';
|
||||||
|
if IsConstValue(AInput) then
|
||||||
|
Halt(12);
|
||||||
|
|
||||||
|
Result := 'Hello ' + AInput;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
MyClass: TMyClass;
|
||||||
|
MyString: String;
|
||||||
|
|
||||||
|
const
|
||||||
|
SomeClass: TClass = TMyClass;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if IsConstValue(TMyClass) then
|
||||||
|
Halt(1);
|
||||||
|
|
||||||
|
MyClass := TMyClass.Create;
|
||||||
|
try
|
||||||
|
if IsConstValue(MyClass) then
|
||||||
|
Halt(3);
|
||||||
|
|
||||||
|
if IsConstValue(MyClass.MyNumber) then
|
||||||
|
Halt(4);
|
||||||
|
|
||||||
|
if not IsConstValue(MyClass.PI) then
|
||||||
|
Halt(5);
|
||||||
|
|
||||||
|
if IsConstValue(MyClass.DoMathAndReturn(5)) then
|
||||||
|
Halt(6);
|
||||||
|
|
||||||
|
if IsConstValue(@MyClass) then
|
||||||
|
Halt(7);
|
||||||
|
finally
|
||||||
|
MyClass.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if IsConstValue(@WorldCopy) then
|
||||||
|
Halt(8);
|
||||||
|
|
||||||
|
WorldCopy('World');
|
||||||
|
WorldConst('World');
|
||||||
|
MyString := 'World';
|
||||||
|
WorldVar(MyString);
|
||||||
|
WorldOut(MyString);
|
||||||
|
|
||||||
|
if IsConstValue(WorldCopy('World')) then
|
||||||
|
Halt(13);
|
||||||
|
|
||||||
|
if IsConstValue(MyString) then
|
||||||
|
Halt(14);
|
||||||
|
|
||||||
|
if IsConstValue(@MyString) then
|
||||||
|
Halt(15);
|
||||||
|
|
||||||
|
UniqueString(MyString);
|
||||||
|
if IsConstValue(MyString) then
|
||||||
|
Halt(16);
|
||||||
|
|
||||||
|
if not IsConstValue('Hello') then
|
||||||
|
Halt(17);
|
||||||
|
|
||||||
|
if not IsConstValue(3.14) then
|
||||||
|
Halt(17);
|
||||||
|
|
||||||
|
if not IsConstValue(12345) then
|
||||||
|
Halt(18);
|
||||||
|
|
||||||
|
if not IsConstValue(5 <> 2) then
|
||||||
|
Halt(19);
|
||||||
|
|
||||||
|
if not IsConstValue(5 - 5 = 0) then
|
||||||
|
Halt(20);
|
||||||
|
|
||||||
|
if IsConstValue(SomeClass) then
|
||||||
|
Halt(21);
|
||||||
|
|
||||||
|
Writeln('Ok');
|
||||||
|
end.
|
34
tests/test/tisconstvalue4.pp
Normal file
34
tests/test/tisconstvalue4.pp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{ %FAIL }
|
||||||
|
program tisconstvalue4;
|
||||||
|
|
||||||
|
{$IFDEF FPC}
|
||||||
|
{$mode Delphi}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
type
|
||||||
|
TMyClass = class
|
||||||
|
const
|
||||||
|
PI = 3.14;
|
||||||
|
private
|
||||||
|
FNumber: Integer;
|
||||||
|
public
|
||||||
|
function DoMathAndReturn(const AValue: Integer): Integer;
|
||||||
|
published
|
||||||
|
property MyNumber: Integer read FNumber;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TClassOf = class of TMyClass;
|
||||||
|
|
||||||
|
function TMyClass.DoMathAndReturn(const AValue: Integer): Integer;
|
||||||
|
begin
|
||||||
|
Result := FNumber * 2;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
// Error: type identifier not allowed here
|
||||||
|
if IsConstValue(TClassOf) then
|
||||||
|
Halt(1);
|
||||||
|
|
||||||
|
Writeln('Ok');
|
||||||
|
end.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user