瀏覽代碼

* 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
        offset in the top-level array/record }
      fqueue_offset: asizeint;
+     fqueued_def: tdef;
 
      { array of caggregateinformation instances }
      faggregateinformation: tfpobjectlist;
@@ -992,8 +993,10 @@ implementation
          an anonymous record also add the next field }
        if assigned(info) then
          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 }
               not is_packed_record_or_object(info.def) then
              pad_next_field(def);
@@ -1109,9 +1112,14 @@ implementation
          begin
            { add padding if necessary, and update the current field/offset }
            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
        { if this is the outer record, no padding is required; the alignment
          has to be specified explicitly in that case via get_final_asmlist() }
@@ -1381,11 +1389,27 @@ implementation
 
 
    procedure ttai_typedconstbuilder.queue_init(todef: tdef);
+     var
+       info: taggregateinformation;
      begin
        { nested call to init? }
        if fqueue_offset<>low(fqueue_offset) then
          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;
+       fqueued_def:=todef;
      end;
 
 

+ 0 - 2
compiler/llvm/nllvmtcon.pas

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