Bläddra i källkod

+ fold the constructs @<record type>(nil^).<field >) and @<record point>(nil)^.<field> used to get the offset of a field into a constant

git-svn-id: trunk@31470 -
florian 10 år sedan
förälder
incheckning
049491a573
3 ändrade filer med 52 tillägg och 0 borttagningar
  1. 1 0
      .gitattributes
  2. 27 0
      compiler/nmem.pas
  3. 24 0
      tests/tbs/tb0612.pp

+ 1 - 0
.gitattributes

@@ -10723,6 +10723,7 @@ tests/tbs/tb0608.pp svneol=native#text/pascal
 tests/tbs/tb0609.pp svneol=native#text/plain
 tests/tbs/tb0610.pp svneol=native#text/pascal
 tests/tbs/tb0611.pp svneol=native#text/pascal
+tests/tbs/tb0612.pp svneol=native#text/pascal
 tests/tbs/tb205.pp svneol=native#text/plain
 tests/tbs/tb610.pp svneol=native#text/pascal
 tests/tbs/tbs0594.pp svneol=native#text/pascal

+ 27 - 0
compiler/nmem.pas

@@ -83,6 +83,7 @@ interface
           function dogetcopy : tnode;override;
           function pass_1 : tnode;override;
           function pass_typecheck:tnode;override;
+          function simplify(forinline : boolean) : tnode; override;
          protected
           mark_read_written: boolean;
           function typecheck_non_proc(realsource: tnode; out res: tnode): boolean; virtual;
@@ -597,6 +598,32 @@ implementation
             { vsf_referred_not_inited                          }
             set_varstate(left,vs_read,[vsf_must_be_valid]);
           end;
+        if not(assigned(result)) then
+          result:=simplify(false);
+      end;
+
+
+    function taddrnode.simplify(forinline : boolean) : tnode;
+      var
+        hsym : tfieldvarsym;
+      begin
+        result:=nil;
+        if ((left.nodetype=subscriptn) and
+          (tsubscriptnode(left).left.nodetype=derefn) and
+          (tsubscriptnode(left).left.resultdef.typ=recorddef) and
+          (tderefnode(tsubscriptnode(left).left).left.nodetype=niln)) or
+          ((left.nodetype=subscriptn) and
+          (tsubscriptnode(left).left.nodetype=typeconvn) and
+          (tsubscriptnode(left).left.resultdef.typ=recorddef) and
+          (ttypeconvnode(tsubscriptnode(left).left).left.nodetype=derefn) and
+          (tderefnode(ttypeconvnode(tsubscriptnode(left).left).left).left.nodetype=niln)) then
+          begin
+            hsym:=tsubscriptnode(left).vs;
+            if tabstractrecordsymtable(hsym.owner).is_packed then
+              result:=cpointerconstnode.create(hsym.fieldoffset div 8,resultdef)
+            else
+              result:=cpointerconstnode.create(hsym.fieldoffset,resultdef);
+          end;
       end;
 
 

+ 24 - 0
tests/tbs/tb0612.pp

@@ -0,0 +1,24 @@
+type
+  trec1 = record
+    l : longint;
+    b : byte;
+  end;
+  prec1 = ^trec1;
+
+  trec2 = packed record
+    a1 : array[0..3] of byte;
+    b : byte;
+  end;
+  prec2 = ^trec2;
+
+begin
+  if ptruint(@trec1(nil^).b)<>4 then
+    halt(1);
+  if ptruint(@prec1(nil)^.b)<>4 then
+    halt(2);
+  if ptruint(@trec2(nil^).b)<>4 then
+    halt(3);
+  if ptruint(@prec2(nil)^.b)<>4 then
+    halt(4);
+end.
+