From ddeab221c023bd3b1b54e8c7b2bcf7bf2063f20b Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Thu, 30 Jul 2015 16:57:49 +0000 Subject: [PATCH] * 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 - --- compiler/aasmcnst.pas | 34 +++++++++++++++++++++++++++++----- compiler/llvm/nllvmtcon.pas | 2 -- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/compiler/aasmcnst.pas b/compiler/aasmcnst.pas index 5bf38a90d0..7904a66ec4 100644 --- a/compiler/aasmcnst.pas +++ b/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; diff --git a/compiler/llvm/nllvmtcon.pas b/compiler/llvm/nllvmtcon.pas index 55b97b1d3a..3d3bac2c24 100644 --- a/compiler/llvm/nllvmtcon.pas +++ b/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;