From 5c81d970b572b20c382c84c7cf43fa282b3c4403 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Wed, 14 Dec 2016 23:52:20 -0600 Subject: [PATCH] Fix issue where statically-evaluated conversions from floating-point values to some integer types could yield wrong values. This occurred because the values were being rounded rather than truncated when converted to long, unsigned long, or unsigned int. This was causing problems in the C6.2.3.5.CC test case when compiled with optimization. The below program demonstrates the problem: #pragma optimize 1 #include int main (void) { long L; unsigned int ui; unsigned long ul; L = -1.5; ui = 1.5; ul = 1.5; printf("%li %u %lu\n", L, ui, ul); /* should print "-1 1 1" */ } --- DAG.pas | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/DAG.pas b/DAG.pas index b0c2ac0..634ffba 100644 --- a/DAG.pas +++ b/DAG.pas @@ -1095,29 +1095,32 @@ case op^.opcode of {check for optimizations of this node} lval := 0 else if rval > 65535.0 then lval := 65535 - else begin - rval := trunc4(rval); - lval := round4(rval); - end; {else} + else + lval := trunc4(rval); op^.left^.rval := 0.0; op^.left^.q := long(lval).lsw; end; - cgLong,cgULong: begin - rval := op^.left^.rval; - if totype.optype = cgULong then begin - if rval < 0 then - rval := 0 - else if rval > 2147483647.0 then - rval := rval - 4294967296.0 - end; {if} + cgLong: begin if rval < -2147483648.0 then lval := $80000000 else if rval > 2147483647.0 then lval := 2147483647 - else begin - rval := trunc4(rval); - lval := round4(rval); - end; {else} + else + lval := trunc4(rval); + op^.left^.rval := 0.0; + op^.left^.lval := lval; + end; + cgULong: begin + if rval < 0.0 then + lval := 0 + else if rval >= 4294967295.0 then + lval := $FFFFFFFF + else if rval > 2147483647.0 then begin + rval := rval - 2147483647.0; + lval := 2147483647 + trunc4(rval); + end {else if} + else + lval := trunc4(rval); op^.left^.rval := 0.0; op^.left^.lval := lval; end;