From de8673af7c0885201f284ffd8851ece2cde8cb18 Mon Sep 17 00:00:00 2001 From: lemon Date: Sat, 14 Mar 2026 17:39:29 +0100 Subject: eval & fold: handle division overflow for MIN/-1 --- c/eval.c | 3 +++ ir/fold.c | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/c/eval.c b/c/eval.c index 721401b..8f458da 100644 --- a/c/eval.c +++ b/c/eval.c @@ -1,5 +1,6 @@ #include "c.h" #include "../ir/ir.h" +#include static int targ2hosttype(enum typetag t) @@ -303,6 +304,7 @@ binop(struct expr *ex, enum evalmode mode) lhs->u /= rhs->u; break; case EDIV|S: if (!rhs->i) return 0; + if (lhs->i == LLONG_MIN && rhs->i == -1) break; lhs->i /= rhs->i; break; case EDIV|F: lhs->f /= rhs->f; break; @@ -311,6 +313,7 @@ binop(struct expr *ex, enum evalmode mode) lhs->u %= rhs->u; break; case EREM|S: if (!rhs->i) return 0; + if (lhs->i == LLONG_MIN && rhs->i == -1) lhs->i = 0; lhs->i %= rhs->i; break; diff --git a/ir/fold.c b/ir/fold.c index 92d17fa..4c9861e 100644 --- a/ir/fold.c +++ b/ir/fold.c @@ -41,9 +41,13 @@ foldint(enum op op, enum irclass k, union ref lr, union ref rr) case Oadd: x = l.u + r.u; break; case Osub: x = l.u - r.u; break; case Omul: x = l.u * r.u; break; - case Odiv: x = w ? l.s / r.s : (int)l.s / (int)r.s; break; + case Odiv: if (r.s == -1 && (w ? l.s == LLONG_MIN : (int)l.s == INT_MIN)) x = l.s; + else x = w ? l.s / r.s : (int)l.s / (int)r.s; + break; case Oudiv: x = w ? l.u / r.u : (uint)l.u / (uint)r.u; break; - case Orem: x = w ? l.s % r.s : (int)l.s % (int)r.s; break; + case Orem: if (r.s == -1 && (w ? l.s == LLONG_MIN : (int)l.s == INT_MIN)) x = 0; + else x = w ? l.s % r.s : (int)l.s % (int)r.s; + break; case Ourem: x = w ? l.u % r.u : (uint)l.u % (uint)r.u; break; case Oand: x = l.u & r.u; break; case Oior: x = l.u | r.u; break; -- cgit v1.2.3