2
0
Эх сурвалжийг харах

+ implement align directive for records, resolves #28927

git-svn-id: trunk@47892 -
florian 4 жил өмнө
parent
commit
eb7702bea4

+ 1 - 0
.gitattributes

@@ -18069,6 +18069,7 @@ tests/webtbs/tw2886.pp svneol=native#text/plain
 tests/webtbs/tw2891.pp svneol=native#text/plain
 tests/webtbs/tw28916.pp svneol=native#text/pascal
 tests/webtbs/tw2892.pp svneol=native#text/plain
+tests/webtbs/tw28927.pp svneol=native#text/pascal
 tests/webtbs/tw28934.pp svneol=native#text/plain
 tests/webtbs/tw28948.pp svneol=native#text/plain
 tests/webtbs/tw28964.pp svneol=native#text/plain

+ 9 - 0
compiler/ptype.pas

@@ -992,6 +992,7 @@ implementation
          old_parse_generic: boolean;
          recst: trecordsymtable;
          hadgendummy : boolean;
+         alignment: Integer;
       begin
          old_current_structdef:=current_structdef;
          old_current_genericdef:=current_genericdef;
@@ -1063,6 +1064,14 @@ implementation
                add_typedconst_init_routine(current_structdef);
              consume(_END);
             end;
+         if (token=_ID) and (pattern='ALIGN') then
+           begin
+             consume(_ID);
+             alignment:=get_intconst.svalue;
+             if not(alignment in [1,2,4,8,16,32,64]) then
+             else
+               recst.recordalignment:=shortint(alignment);
+           end;
          { make the record size aligned (has to be done before inserting the
            parameters, because that may depend on the record's size) }
          recst.addalignmentpadding;

+ 39 - 0
tests/webtbs/tw28927.pp

@@ -0,0 +1,39 @@
+type
+  TRecord1 = record
+  end align 16;
+
+  TRecord2 = record
+  end align 8;
+
+  TRecord3 = record
+  end align 4;
+
+  TRecord1Outer = record  
+    b : Byte;
+    Record1 : TRecord1;
+  end;
+
+  TRecord2Outer = record  
+    b : Byte;
+    Record2 : TRecord2;
+  end;
+
+  TRecord3Outer = record  
+    b : Byte;
+    Record3 : TRecord3;
+  end;
+
+var
+  Record1Outer : TRecord1Outer;
+  Record2Outer : TRecord2Outer;
+  Record3Outer : TRecord3Outer;
+
+begin
+  if PtrUInt(@Record1Outer.Record1) mod 16<>0 then
+    halt(1);
+  if PtrUInt(@Record2Outer.Record2) mod 8<>0 then
+    halt(2);
+  if PtrUInt(@Record3Outer.Record3) mod 4<>0 then
+    halt(3);
+  writeln('ok');
+end.