mirror of
https://github.com/lua/lua.git
synced 2026-10-26 10:35:26 +00:00
Bug: wrong result for (-0.0 - 0)
(exp - i) was being optimized to (exp + (-i)), to use OP_ADDI, but (-0.0 - 0) is -0.0, while (-0.0 + 0) is +0.0, so the case (exp - 0) was excluded from the optimization.
This commit is contained in:
@@ -1542,15 +1542,19 @@ static void codebinK (FuncState *fs, BinOpr opr,
|
||||
|
||||
/* Try to code a binary operator negating its second operand.
|
||||
** For the metamethod, 2nd operand must keep its original value.
|
||||
** As a special case, avoid the optimization for (exp - 0), because
|
||||
** (-0.0 - 0) is -0.0, while (-0.0 + 0) is +0.0.
|
||||
*/
|
||||
static int finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2,
|
||||
OpCode op, int line, TMS event) {
|
||||
OpCode op, int line, TMS event) {
|
||||
if (!isKint(e2))
|
||||
return 0; /* not an integer constant */
|
||||
else {
|
||||
lua_Integer i2 = e2->u.ival;
|
||||
if (!(fitsC(i2) && fitsC(-i2)))
|
||||
return 0; /* not in the proper range */
|
||||
if (event == TM_SUB && i2 == 0)
|
||||
return 0; /* do not optimize (exp - 0) */
|
||||
else { /* operating a small integer constant */
|
||||
int v2 = cast_int(i2);
|
||||
finishbinexpval(fs, e1, e2, op, int2sC(-v2), 0, line, OP_MMBINI, event);
|
||||
|
||||
@@ -838,6 +838,11 @@ do
|
||||
local a1, a2, a3, a4, a5 = 0, 0, "\0\0\0\0\0\0\0\0", 0, "\0\0\0\0\0\0\0\0"
|
||||
assert(a1 == a2 and a2 == a4 and a1 ~= a3)
|
||||
assert(a3 == a5)
|
||||
|
||||
-- Bug since 5.4: Results differ for constant 0 versus variable 0;
|
||||
-- (mz - 0) should be -0.0, but it resulted in +0.0
|
||||
local zi = 0
|
||||
assert(1/(mz - 0) == 1/(mz - zi))
|
||||
end
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user