scc

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

commit 0f0d3edeb1988957d0196482eec84366956cb574
parent 3b5e9eb7079be6f946a66c2b751921723680a5aa
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date:   Sat, 31 Jan 2026 19:05:39 +0100

cc1: Fold constant casts involving floats

Diffstat:
Msrc/cmd/scc-cc/cc1/fold.c | 25+++++++++++++++++++++++--
Atests/cc/execute/0238-fcasts.c | 20++++++++++++++++++++
2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/src/cmd/scc-cc/cc1/fold.c b/src/cmd/scc-cc/cc1/fold.c @@ -416,6 +416,7 @@ foldconst(int type, int op, Type *tp, Symbol *ls, Symbol *rs) static Node * foldcast(Node *np, Node *l) { + long double ld; unsigned long long negmask, mask, u; Type *newtp = np->type, *oldtp = l->type; Symbol aux, *sym, *osym = l->sym; @@ -451,9 +452,29 @@ foldcast(Node *np, Node *l) } break; case FLOAT: - if (oldtp->op == FLOAT) + if (oldtp->op != FLOAT) { + if (oldtp->prop & TSIGNED) + ld = osym->u.i; + else + ld = osym->u.u; + } else if (oldtp == floattype) { + ld = osym->u.f; + } else if (oldtp == doubletype) { + ld = osym->u.d; + } else if (oldtp == ldoubletype) { + ld = osym->u.ld; + } else { return np; - aux.u.f = (oldtp->prop & TSIGNED) ? osym->u.i : osym->u.u; + } + + if (newtp == floattype) + aux.u.f = ld; + else if (newtp == doubletype) + aux.u.d = ld; + else if (newtp == ldoubletype) + aux.u.ld = ld; + else + abort(); break; default: return np; diff --git a/tests/cc/execute/0238-fcasts.c b/tests/cc/execute/0238-fcasts.c @@ -0,0 +1,20 @@ +float f1 = 1.0; +float f2 = 1.0l; +double d1 = 1.0f; +double d2 = 1.0l; + +int +main(void) +{ + double epsilon = 0.001; + + if (f1 < 1.0f - epsilon || f1 > 1.0f + epsilon) + return 1; + if (f2 < 1.0f - epsilon || f2 > 1.0f + epsilon) + return 2; + if (d1 < 1.0f - epsilon || d1 > 1.0f + epsilon) + return 3; + if (d2 < 1.0f - epsilon || d2 > 1.0f + epsilon) + return 4; + return 0; +}