mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 02:28:14 +02:00
* don't keep records in registers if they contain a field that spans the
boundary between two awords, as our subscript code does not handle them correctly (second part of mantis #29669) git-svn-id: trunk@33180 -
This commit is contained in:
parent
7a966345e5
commit
096e1c45d6
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -14969,6 +14969,7 @@ tests/webtbs/tw29585.pp svneol=native#text/plain
|
||||
tests/webtbs/tw29609.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw2966.pp svneol=native#text/plain
|
||||
tests/webtbs/tw29669.pp svneol=native#text/plain
|
||||
tests/webtbs/tw29669a.pp svneol=native#text/plain
|
||||
tests/webtbs/tw2975.pp svneol=native#text/plain
|
||||
tests/webtbs/tw2976.pp svneol=native#text/plain
|
||||
tests/webtbs/tw2983.pp svneol=native#text/plain
|
||||
|
@ -300,6 +300,8 @@ interface
|
||||
function jvm_full_typename(with_package_name: boolean): string;
|
||||
{ check if the symtable contains a float field }
|
||||
function contains_float_field : boolean;
|
||||
{ check if the symtable contains a field that spans an aword boundary }
|
||||
function contains_cross_aword_field: boolean;
|
||||
end;
|
||||
|
||||
pvariantrecdesc = ^tvariantrecdesc;
|
||||
@ -2114,12 +2116,14 @@ implementation
|
||||
recsize:=size;
|
||||
is_intregable:=
|
||||
ispowerof2(recsize,temp) and
|
||||
(((recsize <= sizeof(aint)*2) and
|
||||
not trecorddef(self).contains_cross_aword_field and
|
||||
((recsize<=sizeof(aint)*2) and
|
||||
{ records cannot go into registers on 16 bit targets for now }
|
||||
(sizeof(aint)>2) and
|
||||
not trecorddef(self).contains_float_field) or
|
||||
(recsize <= sizeof(aint))) and
|
||||
not needs_inittable;
|
||||
(sizeof(aint)>2) and
|
||||
(not trecorddef(self).contains_float_field) or
|
||||
(recsize <= sizeof(aint))
|
||||
) and
|
||||
not needs_inittable;
|
||||
{$endif llvm}
|
||||
end;
|
||||
end;
|
||||
@ -4253,6 +4257,41 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function tabstractrecorddef.contains_cross_aword_field: boolean;
|
||||
var
|
||||
i : longint;
|
||||
foffset, fsize: aword;
|
||||
begin
|
||||
result:=true;
|
||||
for i:=0 to symtable.symlist.count-1 do
|
||||
begin
|
||||
if (tsym(symtable.symlist[i]).typ<>fieldvarsym) or
|
||||
(sp_static in tsym(symtable.symlist[i]).symoptions) then
|
||||
continue;
|
||||
if assigned(tfieldvarsym(symtable.symlist[i]).vardef) then
|
||||
begin
|
||||
if is_packed then
|
||||
begin
|
||||
foffset:=tfieldvarsym(symtable.symlist[i]).fieldoffset;
|
||||
fsize:=tfieldvarsym(symtable.symlist[i]).vardef.packedbitsize;
|
||||
end
|
||||
else
|
||||
begin
|
||||
foffset:=tfieldvarsym(symtable.symlist[i]).fieldoffset*8;
|
||||
fsize:=tfieldvarsym(symtable.symlist[i]).vardef.size*8;
|
||||
end;
|
||||
if (foffset div (sizeof(aword)*8)) <> ((foffset+fsize-1) div (sizeof(aword)*8)) then
|
||||
exit;
|
||||
{ search recursively }
|
||||
if (tstoreddef(tfieldvarsym(symtable.symlist[i]).vardef).typ=recorddef) and
|
||||
(tabstractrecorddef(tfieldvarsym(symtable.symlist[i]).vardef).contains_cross_aword_field) then
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
result:=false;
|
||||
end;
|
||||
|
||||
|
||||
{***************************************************************************
|
||||
trecorddef
|
||||
***************************************************************************}
|
||||
|
52
tests/webtbs/tw29669a.pp
Normal file
52
tests/webtbs/tw29669a.pp
Normal file
@ -0,0 +1,52 @@
|
||||
{$mode objfpc}
|
||||
|
||||
program Project1;
|
||||
|
||||
uses
|
||||
SysUtils;
|
||||
|
||||
type
|
||||
TPackedIdLevel1 = 0..255;
|
||||
TPackedIdLevel2 = 0..65535;
|
||||
TPackedIdLevel3 = 0..65535;
|
||||
TPackedIdLevel4 = 0..65535;
|
||||
TPackedIdLevel5 = 0..255;
|
||||
|
||||
TPackedId = bitpacked record
|
||||
clusterId : TPackedIdLevel5;
|
||||
esmId : TPackedIdLevel1;
|
||||
agentId : TPackedIdLevel4;
|
||||
dataSourceId : TPackedIdLevel3;
|
||||
deviceId : TPackedIdLevel2;
|
||||
end;
|
||||
|
||||
function PackedIdToStr(const ipsid : qword) : string;
|
||||
begin
|
||||
result := IntToStr(TPackedId(ipsid).esmId) + '-' +
|
||||
IntToStr(TPackedId(ipsid).deviceId) + '-' +
|
||||
IntToStr(TPackedId(ipsid).dataSourceId) + '-' +
|
||||
IntToStr(TPackedId(ipsid).agentId) + '-' +
|
||||
IntToStr(TPackedId(ipsid).clusterId);
|
||||
if TPackedId(ipsid).clusterid<>123 then
|
||||
halt(1);
|
||||
if TPackedId(ipsid).agentid<>45678 then
|
||||
halt(2);
|
||||
if TPackedId(ipsid).datasourceid<>9012 then
|
||||
halt(3);
|
||||
if TPackedId(ipsid).deviceid<>34567 then
|
||||
halt(4);
|
||||
if TPackedId(ipsid).esmid<>89 then
|
||||
halt(5);
|
||||
|
||||
end;
|
||||
|
||||
var
|
||||
pi: TPackedId;
|
||||
begin
|
||||
pi.clusterid:=123;
|
||||
pi.agentid:=45678;
|
||||
pi.datasourceid:=9012;
|
||||
pi.deviceid:=34567;
|
||||
pi.esmid:=89;
|
||||
writeln(PackedIdToStr(qword(pi)));
|
||||
end.
|
Loading…
Reference in New Issue
Block a user