* 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:
Jonas Maebe 2012-09-14 13:59:59 +00:00
parent 6eccf88499
commit dcdcc6988d
3 changed files with 59 additions and 4 deletions

1
.gitattributes vendored
View File

@ -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

View File

@ -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
View 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.