From ba09d5ee6d8f7846fa7841d81e8be1efbe3de3cf Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sun, 12 Nov 2017 17:21:05 -0600 Subject: [PATCH] Fix issues with addressing/pointer arithmetic using unsigned indexes that generate a displacement of 32K to 64K. These cases should now always work when using an expression of type unsigned as the index. They will work in some cases but not others when using an int as the index: making those cases work consistently would require more extensive changes and/or a speed hit, so I haven't done it for now. Note that this now uses an "unsigned multiply" operation for all 16-bit index computations. This should actually work even when the index is a negative signed value, because it will wind up producing (the low-order 16 bits of) the right answer. The signed multiply, on the other hand, generally does not produce the low-order 16 bits of the right answer in cases where it overflows. The following program is an example that was miscompiled (both with and without optimization): int c[20000] = {3}; int main(void) { int *p; unsigned i = 17000; p = c + 17000u; return *(p-i); /* should return 3 */ } --- DAG.pas | 2 +- Expression.pas | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DAG.pas b/DAG.pas index 2983bcf..2e3f678 100644 --- a/DAG.pas +++ b/DAG.pas @@ -1487,7 +1487,7 @@ case op^.opcode of {check for optimizations of this node} pc_ixa: begin {pc_ixa} if op^.right^.opcode = pc_ldc then begin - optype := op^.right^.optype; + optype := op^.optype; if optype in [cgUByte, cgByte, cgUWord, cgWord] then begin lval := op^.right^.q; if optype = cgUByte then diff --git a/Expression.pas b/Expression.pas index 4d9d89b..84ca69d 100644 --- a/Expression.pas +++ b/Expression.pas @@ -2185,7 +2185,7 @@ case tp of else if smallMemoryModel and (size = long(size).lsw) then begin if size <> 1 then begin Gen1t(pc_ldc, long(size).lsw, cgWord); - Gen0(pc_mpi); + Gen0(pc_umi); end; {if} Gen2(pc_cnv, ord(tp), ord(cgLong)); Gen0(op);