Browse Source

* fixed "byte/word/... ptr []" and "byte/word/..([])" typecasted expressions
in case the memory expression contains a record subscription (mantis
#16700)

git-svn-id: trunk@15408 -

Jonas Maebe 15 năm trước cách đây
mục cha
commit
6d6892bec6
3 tập tin đã thay đổi với 72 bổ sung1 xóa
  1. 1 0
      .gitattributes
  2. 11 1
      compiler/x86/rax86int.pas
  3. 60 0
      tests/webtbs/tw16700.pp

+ 1 - 0
.gitattributes

@@ -10499,6 +10499,7 @@ tests/webtbs/tw16377.pp svneol=native#text/plain
 tests/webtbs/tw16402.pp svneol=native#text/plain
 tests/webtbs/tw1658.pp svneol=native#text/plain
 tests/webtbs/tw16668.pp svneol=native#text/plain
+tests/webtbs/tw16700.pp svneol=native#text/plain
 tests/webtbs/tw1677.pp svneol=native#text/plain
 tests/webtbs/tw1681.pp svneol=native#text/plain
 tests/webtbs/tw1696.pp svneol=native#text/plain

+ 11 - 1
compiler/x86/rax86int.pas

@@ -1653,7 +1653,11 @@ Unit Rax86int;
                   end;
                 Consume(AS_PTR);
                 oper.InitRef;
+                { if the operand subscripts a record, the typesize will be
+                  rest -> save it here and restore it afterwards }
+                l:=oper.typesize;
                 BuildOperand(oper,false);
+                oper.setsize(l,true);
               end;
 
             AS_ID : { A constant expression, or a Variable ref. }
@@ -1812,14 +1816,20 @@ Unit Rax86int;
                   AS_QWORD : oper.typesize:=8;
                   AS_DQWORD : oper.typesize:=16;
                   AS_TBYTE : oper.typesize:=10;
+                  else
+                    internalerror(2010061101);
                 end;
                 Consume(actasmtoken);
                 if (actasmtoken=AS_LPAREN) then
                   begin
-                    { Support Type([Reference]) }
+                    { Support "xxx ptr [Reference]" }
+                    { in case the expression subscripts a record, the typesize
+                      is reset, so save the explicit size we set above }
+                    l:=oper.typesize;
                     Consume(AS_LPAREN);
                     BuildOperand(oper,true);
                     Consume(AS_RPAREN);
+                    oper.setsize(l,true);
                   end;
               end;
 

+ 60 - 0
tests/webtbs/tw16700.pp

@@ -0,0 +1,60 @@
+{ %cpu=i386 }
+{ %opt=-Cg- }
+
+{$ifdef fpc}
+{$mode delphi}
+{$endif}
+
+program test;
+type
+  tr_rec=object
+    x: integer;
+    r: record
+      a,b: integer;
+    end;
+    function f:integer;
+  end;
+
+var
+  x1,a1,a2,b1: byte;
+  b2: longint;
+
+function tr_rec.f:integer;
+asm
+  mov dl,byte ptr [eax].tr_rec.x
+  mov x1,dl
+  mov dl,byte ptr [eax].tr_rec.r
+  mov a1,dl
+  mov dl,byte ptr [eax].tr_rec.r.a
+  mov a2,dl
+  mov dl,byte ptr [eax].tr_rec.r.b
+  mov b1,dl
+  movzx eax,byte ptr [eax].tr_rec.r.b
+  mov b2,eax
+  end;
+
+var
+  v: tr_rec;
+begin
+  v.x:=4;
+  v.r.a:=10;
+  v.r.b:=17;
+  writeln(v.f,' (should be 17)');
+  writeln(x1,' (should be 4)');
+  writeln(a1,' (should be 10)');
+  writeln(a2,' (should be 10)');
+  writeln(b1,' (should be 17)');
+  writeln(b2,' (should be 17)');
+  if v.f<>17 then
+    halt(1);
+  if x1<>4 then
+    halt(2);
+  if a1<>10 then
+    halt(3);
+  if a2<>10 then
+    halt(4);
+  if b1<>17 then
+    halt(5);
+  if b2<>17 then
+    halt(6);
+end.