Просмотр исходного кода

* handle aligned assignments with size < sizeof(aint) properly, resolves #19355

git-svn-id: trunk@17468 -
florian 14 лет назад
Родитель
Сommit
f1b13dca19
1 измененных файлов с 10 добавлено и 5 удалено
  1. 10 5
      compiler/ncgld.pas

+ 10 - 5
compiler/ncgld.pas

@@ -567,6 +567,7 @@ implementation
          otlabel,hlabel,oflabel : tasmlabel;
          otlabel,hlabel,oflabel : tasmlabel;
          href : treference;
          href : treference;
          releaseright : boolean;
          releaseright : boolean;
+         alignmentrequirement,
          len : aint;
          len : aint;
          r : tregister;
          r : tregister;
          oldflowcontrol : tflowcontrol;
          oldflowcontrol : tflowcontrol;
@@ -777,13 +778,17 @@ implementation
 { TODO: HACK: unaligned test, maybe remove all unaligned locations (array of char) from the compiler}
 { TODO: HACK: unaligned test, maybe remove all unaligned locations (array of char) from the compiler}
                             { Use unaligned copy when the offset is not aligned }
                             { Use unaligned copy when the offset is not aligned }
                             len:=left.resultdef.size;
                             len:=left.resultdef.size;
-                            if (right.location.reference.offset mod sizeof(aint)<>0) or
-                              (left.location.reference.offset mod sizeof(aint)<>0) or
-                              (right.resultdef.alignment<sizeof(aint)) or
+
+                            { data smaller than an aint has less alignment requirements }
+                            alignmentrequirement:=min(len,sizeof(aint));
+
+                            if (right.location.reference.offset mod alignmentrequirement<>0) or
+                              (left.location.reference.offset mod alignmentrequirement<>0) or
+                              (right.resultdef.alignment<alignmentrequirement) or
                               ((right.location.reference.alignment<>0) and
                               ((right.location.reference.alignment<>0) and
-                               (right.location.reference.alignment<sizeof(aint))) or
+                               (right.location.reference.alignment<alignmentrequirement)) or
                               ((left.location.reference.alignment<>0) and
                               ((left.location.reference.alignment<>0) and
-                               (left.location.reference.alignment<sizeof(aint))) then
+                               (left.location.reference.alignment<alignmentrequirement)) then
                               cg.g_concatcopy_unaligned(current_asmdata.CurrAsmList,right.location.reference,left.location.reference,len)
                               cg.g_concatcopy_unaligned(current_asmdata.CurrAsmList,right.location.reference,left.location.reference,len)
                             else
                             else
                               cg.g_concatcopy(current_asmdata.CurrAsmList,right.location.reference,left.location.reference,len);
                               cg.g_concatcopy(current_asmdata.CurrAsmList,right.location.reference,left.location.reference,len);