Browse Source

* handle enums with a packenum setting that is larger than necessary to store
all of their values, when kept in a bitpacked array, properly via
pass_typecheck rather than hacking location.size in pass_generate_code:
o the old fix was incomplete (it didn't handle non-constant indices)
o the old fix didn't work for llvm (since it uses defs rather than
location.size)

git-svn-id: trunk@33943 -

Jonas Maebe 9 years ago
parent
commit
5af40f22e8
3 changed files with 15 additions and 8 deletions
  1. 0 7
      compiler/ncgmem.pas
  2. 13 0
      compiler/nmem.pas
  3. 2 1
      tests/test/tparray12.pp

+ 0 - 7
compiler/ncgmem.pas

@@ -1030,13 +1030,6 @@ implementation
                   update_reference_offset(location.reference,extraoffset,bytemulsize);
                   update_reference_offset(location.reference,extraoffset,bytemulsize);
                   { adjust alignment after this change }
                   { adjust alignment after this change }
                   location.reference.alignment:=newalignment(location.reference.alignment,extraoffset*bytemulsize);
                   location.reference.alignment:=newalignment(location.reference.alignment,extraoffset*bytemulsize);
-                  { don't do this for floats etc.; needed to properly set the }
-                  { size for bitpacked arrays (e.g. a bitpacked array of      }
-                  { enums who are size 2 but fit in one byte -> in the array  }
-                  { they will be one byte and have to be stored like that)    }
-                  if is_packed_array(left.resultdef) and
-                     (tcgsize2size[newsize] <> bytemulsize) then
-                    newsize:=int_cgsize(bytemulsize);
                 end
                 end
               else
               else
                 begin
                 begin

+ 13 - 0
compiler/nmem.pas

@@ -1037,6 +1037,19 @@ implementation
                          hightree.free;
                          hightree.free;
                        end;
                        end;
                    end;
                    end;
+               { in case of a bitpacked array of enums that are size 2 (due to
+                 packenum 2) but whose values all fit in one byte, the size of
+                 bitpacked array elements will be 1 byte while the resultdef of
+                 will currently say it's two bytes) -> create a temp enumdef
+                 with packenum=1 for the resultdef as subtype of the main
+                 enumdef }
+               if is_enum(resultdef) and
+                  is_packed_array(left.resultdef) and
+                  ((tarraydef(left.resultdef).elepackedbitsize div 8) <> resultdef.size) then
+                 begin
+                   resultdef:=cenumdef.create_subrange(tenumdef(resultdef),tenumdef(resultdef).min,tenumdef(resultdef).max);
+                   tenumdef(resultdef).calcsavesize(1);
+                 end
              end;
              end;
            pointerdef :
            pointerdef :
              begin
              begin

+ 2 - 1
tests/test/tparray12.pp

@@ -14,7 +14,8 @@ begin
   a[3]:=ec;
   a[3]:=ec;
   a[6]:=ef;
   a[6]:=ef;
   a[5]:=ee;
   a[5]:=ee;
-  a[4]:=ed;
+  i:=4;
+  a[i]:=ed;
   for i := 1 to 6 do
   for i := 1 to 6 do
     begin writeln(tb(a)[i]);
     begin writeln(tb(a)[i]);
     if (tb(a)[i] <> res[i]) then
     if (tb(a)[i] <> res[i]) then