Browse Source

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 -

tom_at_work 17 years ago
parent
commit
20737f0ac1
3 changed files with 41 additions and 7 deletions
  1. 13 1
      compiler/ncgrtti.pas
  2. 3 3
      rtl/inc/text.inc
  3. 25 3
      tests/webtbs/tw10033.pp

+ 13 - 1
compiler/ncgrtti.pas

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

+ 3 - 3
rtl/inc/text.inc

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

+ 25 - 3
tests/webtbs/tw10033.pp

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