summaryrefslogtreecommitdiff
path: root/src/lj_opt_fold.c
diff options
context:
space:
mode:
authorMike Pall <mike>2022-12-22 00:03:06 +0100
committerMike Pall <mike>2022-12-22 00:03:06 +0100
commit8a5e398c52c7f8ca3e1a0e574cc2ba38224b759b (patch)
treedae089564f58db2963bae8e3530c1faae104cc61 /src/lj_opt_fold.c
parentb2791179ef96d652d00d78d2a8780af690537f6a (diff)
downloadluajit2-8a5e398c52c7f8ca3e1a0e574cc2ba38224b759b.tar.gz
Avoid negation of signed integers in C that may hold INT*_MIN.
Reported by minoki. Recent C compilers 'take advantage' of the undefined behavior. This completely changes the meaning of expressions like (k == -k).
Diffstat (limited to 'src/lj_opt_fold.c')
-rw-r--r--src/lj_opt_fold.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index e9a6532a..482abdef 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -236,7 +236,7 @@ static int32_t kfold_intop(int32_t k1, int32_t k2, IROp op)
case IR_SUB: k1 -= k2; break;
case IR_MUL: k1 *= k2; break;
case IR_MOD: k1 = lj_vm_modi(k1, k2); break;
- case IR_NEG: k1 = -k1; break;
+ case IR_NEG: k1 = (int32_t)(~(uint32_t)k1+1u); break;
case IR_BAND: k1 &= k2; break;
case IR_BOR: k1 |= k2; break;
case IR_BXOR: k1 ^= k2; break;
@@ -1160,7 +1160,7 @@ LJFOLDF(simplify_intsub_k)
if (fright->i == 0) /* i - 0 ==> i */
return LEFTFOLD;
fins->o = IR_ADD; /* i - k ==> i + (-k) */
- fins->op2 = (IRRef1)lj_ir_kint(J, -fright->i); /* Overflow for -2^31 ok. */
+ fins->op2 = (IRRef1)lj_ir_kint(J, (int32_t)(~(uint32_t)fright->i+1u)); /* Overflow for -2^31 ok. */
return RETRYFOLD;
}
@@ -1191,7 +1191,7 @@ LJFOLDF(simplify_intsub_k64)
if (k == 0) /* i - 0 ==> i */
return LEFTFOLD;
fins->o = IR_ADD; /* i - k ==> i + (-k) */
- fins->op2 = (IRRef1)lj_ir_kint64(J, (uint64_t)-(int64_t)k);
+ fins->op2 = (IRRef1)lj_ir_kint64(J, ~k+1u);
return RETRYFOLD;
}