Browse Source

* give an error when trying to use the offset of a non-byte-aligned field
of a bitpacked record in assembler code
* convert the offsets of byte-aligned fields of bitpacked records from bits
to bytes (mantis #13563)

git-svn-id: trunk@13027 -

Jonas Maebe 16 years ago
parent
commit
10158da60e
4 changed files with 95 additions and 3 deletions
  1. 2 0
      .gitattributes
  2. 13 3
      compiler/rautils.pas
  3. 32 0
      tests/webtbf/tw13563a.pp
  4. 48 0
      tests/webtbs/tw13563.pp

+ 2 - 0
.gitattributes

@@ -8291,6 +8291,7 @@ tests/webtbf/tw12933.pp svneol=native#text/plain
 tests/webtbf/tw1306.pp svneol=native#text/plain
 tests/webtbf/tw1316.pp svneol=native#text/plain
 tests/webtbf/tw1328.pp svneol=native#text/plain
+tests/webtbf/tw13563a.pp svneol=native#text/plain
 tests/webtbf/tw1365.pp svneol=native#text/plain
 tests/webtbf/tw1395.pp svneol=native#text/plain
 tests/webtbf/tw1407.pp svneol=native#text/plain
@@ -8823,6 +8824,7 @@ tests/webtbs/tw1348.pp svneol=native#text/plain
 tests/webtbs/tw1351.pp svneol=native#text/plain
 tests/webtbs/tw13536.pp svneol=native#text/plain
 tests/webtbs/tw13553.pp svneol=native#text/plain
+tests/webtbs/tw13563.pp svneol=native#text/plain
 tests/webtbs/tw1364.pp svneol=native#text/plain
 tests/webtbs/tw1365.pp svneol=native#text/plain
 tests/webtbs/tw1374.pp svneol=native#text/plain

+ 13 - 3
compiler/rautils.pas

@@ -789,7 +789,12 @@ Begin
   case sym.typ of
     fieldvarsym :
       begin
-        setconst(tfieldvarsym(sym).fieldoffset);
+        if not tabstractrecordsymtable(sym.owner).is_packed then
+          setconst(tfieldvarsym(sym).fieldoffset)
+        else if tfieldvarsym(sym).fieldoffset mod 8 = 0 then
+          setconst(tfieldvarsym(sym).fieldoffset div 8)
+        else
+          Message(asmr_e_packed_element);
         hasvar:=true;
         SetupVar:=true;
       end;
@@ -863,7 +868,7 @@ Begin
                else
                  begin
                    if (harrdef.elepackedbitsize mod 8) = 0 then
-                     SetSize(harrdef.elepackedbitsize div 8,false);
+                     SetSize(harrdef.elepackedbitsize div 8,false)
                  end;
             end;
         end;
@@ -1338,7 +1343,12 @@ Begin
        fieldvarsym :
          with Tfieldvarsym(sym) do
            begin
-             inc(Offset,fieldoffset);
+             if not tabstractrecordsymtable(sym.owner).is_packed then
+               inc(Offset,fieldoffset)
+             else if tfieldvarsym(sym).fieldoffset mod 8 = 0 then
+               inc(Offset,fieldoffset div 8)
+             else
+               Message(asmr_e_packed_element);
              size:=getsize;
              case vardef.typ of
                arraydef :

+ 32 - 0
tests/webtbf/tw13563a.pp

@@ -0,0 +1,32 @@
+{ %cpu=i386 }
+{ %fail }
+
+program bug;
+type
+  br=bitpacked record	//Note! "bitpacked"
+    l:0..31;
+    m:0..31;
+    h:0..63;
+  end;
+var
+
+test:br;
+{$asmmode att}
+begin
+  with test do
+  begin
+    l:=4;
+    m:=8;
+    l:=$f
+  end;
+  asm
+    movb br.m,%al	//eax should be 4,but it is 32. Eight times. error!
+    movb test.m,%al  //eax should be 8,but it is, a strange number. error!
+  end;
+
+  asm
+    movb $br.m/8,%al		//OK, eax is 4 now, it is the right offset.
+    movb test+br.m/8,%al	//OK, eax is 8 now, it is right, too.
+  end;
+end.
+

+ 48 - 0
tests/webtbs/tw13563.pp

@@ -0,0 +1,48 @@
+{ %cpu=i386 }
+{ %opt=-Cg- }
+
+program bug;
+type
+  br=bitpacked record	//Note! "bitpacked"
+    l:longword;
+    m:longword;
+    h:longword;
+  end;
+
+var
+  l,
+  m,
+  moffs,
+  h: longword;
+
+test:br;
+
+{$asmmode att}
+begin
+  with test do
+  begin
+    l:=4;
+    m:=8;
+    h:=$f
+  end;
+  asm
+    movl br.m,%eax	//eax should be 4,but it is 32. Eight times. error!
+    movl %eax, moffs
+    movl test.m,%eax  //eax should be 8,but it is, a strange number. error!
+    movl %eax, m
+    movl test.l,%eax
+    movl %eax, l
+    movl test.h,%eax
+    movl %eax, h
+  end;
+
+  if (moffs<>4) then
+    halt(1);
+  if (m<>8) then
+    halt(2);
+  if (l<>4) then
+    halt(3);
+  if (h<>$f) then
+    halt(4);
+end.
+