diff options
author | Mike Pall <mike> | 2022-12-22 00:03:06 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2022-12-22 00:03:06 +0100 |
commit | 8a5e398c52c7f8ca3e1a0e574cc2ba38224b759b (patch) | |
tree | dae089564f58db2963bae8e3530c1faae104cc61 /src/lj_opt_fold.c | |
parent | b2791179ef96d652d00d78d2a8780af690537f6a (diff) | |
download | luajit2-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.c | 6 |
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; } |