fix webts/tw10033 on ppc64:

* correctly write rtti for enumerations (missing alignment instructions on CPUs requiring proper alignment, breaking on architectures with 64 bit pointers)
* fix hardcoded offsets in fpc_write_text_enum
* updated example program

git-svn-id: trunk@10728 -
This commit is contained in:
tom_at_work 2008-04-19 22:06:18 +00:00
parent 61f266bf4f
commit 20737f0ac1
3 changed files with 41 additions and 7 deletions

View File

@ -405,9 +405,11 @@ implementation
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otULong));
end;
if (tf_requires_proper_alignment in target_info.flags) then
current_asmdata.asmlists[al_rtti].concat(Cai_align.Create(sizeof(TConstPtrUInt)));
current_asmdata.asmlists[al_rtti].concat(Cai_align.Create(longint(def.size)));
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(def.min));
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(def.max));
if (tf_requires_proper_alignment in target_info.flags) then
current_asmdata.asmlists[al_rtti].concat(Cai_align.Create(sizeof(TConstPtrUint)));
if assigned(def.basedef) then
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(def.basedef,rt)))
else
@ -951,6 +953,8 @@ implementation
asmlists[al_rtti].concat(Tai_const.create_32bit(longint(mode)));
if mode=lookup then
begin
if (tf_requires_proper_alignment in target_info.flags) then
current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
o:=syms[0].value; {Start with min value.}
for i:=0 to sym_count-1 do
begin
@ -968,7 +972,11 @@ implementation
asmlists[al_rtti].concat(Tai_const.create_32bit(sym_count));
for i:=0 to sym_count-1 do
begin
if (tf_requires_proper_alignment in target_info.flags) then
current_asmdata.asmlists[al_rtti].concat(cai_align.Create(4));
asmlists[al_rtti].concat(Tai_const.create_32bit(syms[i].value));
if (tf_requires_proper_alignment in target_info.flags) then
current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
asmlists[al_rtti].concat(Tai_const.create_sym_offset(mainrtti,st+offsets[i]));
end;
end;
@ -1057,7 +1065,11 @@ implementation
asmlists[al_rtti].concat(Tai_const.create_32bit(sym_count));
for i:=0 to sym_count-1 do
begin
if (tf_requires_proper_alignment in target_info.flags) then
current_asmdata.asmlists[al_rtti].concat(cai_align.Create(4));
asmlists[al_rtti].concat(Tai_const.create_32bit(syms[i].value));
if (tf_requires_proper_alignment in target_info.flags) then
current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
asmlists[al_rtti].concat(Tai_const.create_sym_offset(mainrtti,st+offsets[i]));
end;
asmlists[al_rtti].concat(Tai_symbol_end.create(rttilab));

View File

@ -712,7 +712,7 @@ type Ptypeinfo=^Ttypeinfo;
Penuminfo=^Tenuminfo;
Tenuminfo={$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}packed{$endif}record
ordtype:byte;
minvalue,maxvalue:longint;
minvalue, maxvalue:longint;
basetype:pointer;
namelist:shortstring;
end;
@ -742,7 +742,7 @@ begin
{The compiler did generate a lookup table.}
offset:=2+length(Ptypeinfo(typinfo)^.name);
{$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
offset:=(offset+sizeof(sizeint)-1) and not (sizeof(sizeint)-1);
offset:=align(offset, sizeof(ptrint));
{$endif}
with Penuminfo(Pbyte(typinfo)+offset)^ do
begin
@ -754,7 +754,7 @@ begin
dec(ordinal,minvalue);
end;
{Get the address of the string.}
p:=Pshortstring((PPpointer(ord2strindex+4)+ordinal)^);
p:=Pshortstring((PPpointer(ord2strindex+align(sizeof(longint), sizeof(ptrint)))+ordinal)^);
if p=nil then
begin
inoutres:=107; {Invalid ordinal value for this enum.}

View File

@ -1,9 +1,31 @@
{$apptype console}
type Txxx = set of (one,two,three);
// tests writing of high()/low() of enumeration values, i.e.
// writing and reading of rtti for enums, both "dense" and
// "sparse" enumerations (different rtti is generated and
// different code used for generating and reading)
{$mode objfpc}
type
// "dense" enumeration
Tx = (one,two,three);
Txxx = set of Tx;
// "sparse" enumeration
Ty =(zero := 0, ten := 10, twenty := 20);
Tyyy = set of Ty;
var x : txxx;
procedure error(number : longint);
begin
writeln('error ', number);
halt(number);
end;
var
x : txxx;
y : tyyy;
err : word;
begin
writeln(low(x));
writeln(high(x));
writeln(low(y));
writeln(high(y));
end.