Преглед на файлове

* when starting a queued expression, immediately emit any necessary padding
bytes,becayse if we emit them at the end then we may interpret the first
padding byte as the final component of the queued expression

git-svn-id: trunk@31246 -

Jonas Maebe преди 10 години
родител
ревизия
ddeab221c0
променени са 2 файла, в които са добавени 29 реда и са изтрити 7 реда
  1. 29 5
      compiler/aasmcnst.pas
  2. 0 2
      compiler/llvm/nllvmtcon.pas

+ 29 - 5
compiler/aasmcnst.pas

@@ -183,6 +183,7 @@ type
      { while queueing elements of a compound expression, this is the current
      { while queueing elements of a compound expression, this is the current
        offset in the top-level array/record }
        offset in the top-level array/record }
      fqueue_offset: asizeint;
      fqueue_offset: asizeint;
+     fqueued_def: tdef;
 
 
      { array of caggregateinformation instances }
      { array of caggregateinformation instances }
      faggregateinformation: tfpobjectlist;
      faggregateinformation: tfpobjectlist;
@@ -992,8 +993,10 @@ implementation
          an anonymous record also add the next field }
          an anonymous record also add the next field }
        if assigned(info) then
        if assigned(info) then
          begin
          begin
-           if ((info.def.typ=recorddef) or
-               is_object(info.def)) and
+           { queue_init already adds padding }
+           if not queue_is_active and
+               (is_record(info.def) or
+                is_object(info.def)) and
               { may add support for these later }
               { may add support for these later }
               not is_packed_record_or_object(info.def) then
               not is_packed_record_or_object(info.def) then
              pad_next_field(def);
              pad_next_field(def);
@@ -1109,9 +1112,14 @@ implementation
          begin
          begin
            { add padding if necessary, and update the current field/offset }
            { add padding if necessary, and update the current field/offset }
            info:=curagginfo;
            info:=curagginfo;
-           if is_record(curagginfo.def) or
-              is_object(curagginfo.def) then
-             pad_next_field(def);
+           if (is_record(curagginfo.def) or
+               is_object(curagginfo.def)) and
+              not is_packed_record_or_object(curagginfo.def) then
+             begin
+               if queue_is_active then
+                 internalerror(2015073001);
+               pad_next_field(def);
+             end;
          end
          end
        { if this is the outer record, no padding is required; the alignment
        { if this is the outer record, no padding is required; the alignment
          has to be specified explicitly in that case via get_final_asmlist() }
          has to be specified explicitly in that case via get_final_asmlist() }
@@ -1381,11 +1389,27 @@ implementation
 
 
 
 
    procedure ttai_typedconstbuilder.queue_init(todef: tdef);
    procedure ttai_typedconstbuilder.queue_init(todef: tdef);
+     var
+       info: taggregateinformation;
      begin
      begin
        { nested call to init? }
        { nested call to init? }
        if fqueue_offset<>low(fqueue_offset) then
        if fqueue_offset<>low(fqueue_offset) then
          internalerror(2014062101);
          internalerror(2014062101);
+
+       { insert padding bytes before starting the queue, so that the first
+         padding byte won't be interpreted as the emitted value for this queue }
+       info:=curagginfo;
+       if assigned(info) then
+         begin
+           if ((info.def.typ=recorddef) or
+               is_object(info.def)) and
+              { may add support for these later }
+              not is_packed_record_or_object(info.def) then
+             pad_next_field(todef);
+         end;
+
        fqueue_offset:=0;
        fqueue_offset:=0;
+       fqueued_def:=todef;
      end;
      end;
 
 
 
 

+ 0 - 2
compiler/llvm/nllvmtcon.pas

@@ -51,7 +51,6 @@ interface
        { set the default value for caggregateinformation (= tllvmaggregateinformation) }
        { set the default value for caggregateinformation (= tllvmaggregateinformation) }
        class constructor classcreate;
        class constructor classcreate;
      protected
      protected
-      fqueued_def: tdef;
       fqueued_tai,
       fqueued_tai,
       flast_added_tai: tai;
       flast_added_tai: tai;
       fqueued_tai_opidx: longint;
       fqueued_tai_opidx: longint;
@@ -420,7 +419,6 @@ implementation
       fqueued_tai:=nil;
       fqueued_tai:=nil;
       flast_added_tai:=nil;
       flast_added_tai:=nil;
       fqueued_tai_opidx:=-1;
       fqueued_tai_opidx:=-1;
-      fqueued_def:=todef;
     end;
     end;