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:
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;
+}