mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 00:08:12 +02:00
* if an agregate contains unaligned fields, it has to be passed via memory
(mantis #22878) git-svn-id: trunk@22390 -
This commit is contained in:
parent
6eccf88499
commit
dcdcc6988d
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -12827,6 +12827,7 @@ tests/webtbs/tw2280.pp svneol=native#text/plain
|
||||
tests/webtbs/tw22860.pp svneol=native#text/plain
|
||||
tests/webtbs/tw22864.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw22869.pp svneol=native#text/plain
|
||||
tests/webtbs/tw22878.pp svneol=native#text/plain
|
||||
tests/webtbs/tw2289.pp svneol=native#text/plain
|
||||
tests/webtbs/tw2291.pp svneol=native#text/plain
|
||||
tests/webtbs/tw2294.pp svneol=native#text/plain
|
||||
|
@ -342,6 +342,7 @@ unit cpupara;
|
||||
i,
|
||||
words,
|
||||
num: longint;
|
||||
checkalignment: boolean;
|
||||
begin
|
||||
result:=init_aggregate_classification(def,varspez,words,classes);
|
||||
if (words=0) then
|
||||
@ -354,6 +355,7 @@ unit cpupara;
|
||||
continue;
|
||||
vs:=tfieldvarsym(tabstractrecorddef(def).symtable.symlist[i]);
|
||||
num:=-1;
|
||||
checkalignment:=true;
|
||||
if not tabstractrecordsymtable(tabstractrecorddef(def).symtable).is_packed then
|
||||
begin
|
||||
new_byte_offset:=byte_offset+vs.fieldoffset;
|
||||
@ -363,11 +365,25 @@ unit cpupara;
|
||||
begin
|
||||
new_byte_offset:=byte_offset+vs.fieldoffset div 8;
|
||||
if (vs.vardef.typ in [orddef,enumdef]) then
|
||||
{ calculate the number of bytes spanned by
|
||||
this bitpacked field }
|
||||
size:=((vs.fieldoffset+vs.vardef.packedbitsize+7) div 8)-(vs.fieldoffset div 8)
|
||||
begin
|
||||
{ calculate the number of bytes spanned by
|
||||
this bitpacked field }
|
||||
size:=((vs.fieldoffset+vs.vardef.packedbitsize+7) div 8)-(vs.fieldoffset div 8);
|
||||
{ our bitpacked fields are interpreted as always being
|
||||
aligned, because unlike in C we don't have char:1, int:1
|
||||
etc (so everything is basically a char:x) }
|
||||
checkalignment:=false;
|
||||
end
|
||||
else
|
||||
size:=vs.vardef.size
|
||||
size:=vs.vardef.size;
|
||||
end;
|
||||
{ If [..] an object [..] contains unaligned fields, it has class
|
||||
MEMORY }
|
||||
if checkalignment and
|
||||
(align(new_byte_offset,vs.vardef.structalignment)<>new_byte_offset) then
|
||||
begin
|
||||
result:=0;
|
||||
exit;
|
||||
end;
|
||||
num:=classify_aggregate_element(vs.vardef,varspez,size,classes,new_byte_offset);
|
||||
if (num=0) then
|
||||
@ -413,6 +429,13 @@ unit cpupara;
|
||||
begin
|
||||
{ size does not change }
|
||||
new_byte_offset:=byte_offset+i*elesize;
|
||||
{ If [..] an object [..] contains unaligned fields, it has class
|
||||
MEMORY }
|
||||
if align(new_byte_offset,def.alignment)<>new_byte_offset then
|
||||
begin
|
||||
result:=0;
|
||||
exit;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
|
31
tests/webtbs/tw22878.pp
Normal file
31
tests/webtbs/tw22878.pp
Normal file
@ -0,0 +1,31 @@
|
||||
program gr;
|
||||
{$mode objfpc}
|
||||
type
|
||||
t0= record
|
||||
p: pointer;
|
||||
end;
|
||||
t1= packed record
|
||||
u16: word;
|
||||
data: t0;
|
||||
end;
|
||||
|
||||
td= class
|
||||
function return: t1;
|
||||
end;
|
||||
function td.return: t1;
|
||||
begin
|
||||
return.u16:=1;
|
||||
return.data.p:=pointer(2);
|
||||
end;
|
||||
var
|
||||
c: td;
|
||||
r: t1;
|
||||
begin
|
||||
c:=td.create;
|
||||
r:=c.return;
|
||||
if r.u16<>1 then
|
||||
halt(1);
|
||||
if r.data.p<>pointer(2) then
|
||||
halt(2);
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user