scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 2bc598101275d978b5494d034bd71d8e2b443f4a
parent c3dde9b82a4e46f51444725132ecd65c7bdeedbe
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date:   Mon, 23 Mar 2026 11:28:40 +0100

cc1: Don't reduce modulus in signed types

Reducing modulus to and  is valid only in types without sign,
because in case of having a sign the bitwise operation does
not consider the sign bit.

Diffstat:
Msrc/cmd/scc-cc/cc1/fold.c | 8++++++--
Atests/cc/execute/0249-mod.c | 15+++++++++++++++
Mtests/cc/execute/scc-tests.lst | 1+
3 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/src/cmd/scc-cc/cc1/fold.c b/src/cmd/scc-cc/cc1/fold.c @@ -797,6 +797,9 @@ reduce(Node *np) Node *aux, *aux2; int op = np->op; + if (np->type->prop & TSIGNED) + return; + switch (op) { case OMOD: /* i % 2^n => i & n-1 */ @@ -886,9 +889,10 @@ repeat: associative(np); } np = fold(np); - if (!isfloat) + if (!isfloat) { np = identity(np); - reduce(np); + reduce(np); + } break; } diff --git a/tests/cc/execute/0249-mod.c b/tests/cc/execute/0249-mod.c @@ -0,0 +1,15 @@ +int +main(void) +{ + int a = -1; + unsigned b = 3, c = 10; + + if (!(a % 2 == -1)) + return 1; + if (!(b % 2 == 1)) + return 2; + if (!(c % 8 == 2)) + return 2; + + return 0; +} diff --git a/tests/cc/execute/scc-tests.lst b/tests/cc/execute/scc-tests.lst @@ -239,3 +239,4 @@ 0246-branch.c 0247-float.c 0248-enum.c +0249-mod.c