ref: a926e8f5971ee8598fc7083ad9911da0c23fc76d
parent: 1a1f248fcb208d1c374b8be41bed65bcea24afae
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed Nov 17 02:50:09 EST 2021
cc1: Convert to variable unfoldable constants When a constant expression cannot be folded then it is not constant anymore because it needs run time operations to perform it. it also derives to the fact that if a initializer contains one of these expressions then the full initializer is not constant.
--- a/src/cmd/cc/cc1/fold.c
+++ b/src/cmd/cc/cc1/fold.c
@@ -454,8 +454,10 @@
type = UNSIGNED;
case PTR:
case FLOAT:
- if ((p = foldconst(type, op, tp, ls, rs)) == NULL)
+ if ((p = foldconst(type, op, tp, ls, rs)) == NULL) {
+ np->flags &= ~NCONST;
return NULL;
+ }
freetree(np);
return p;
default:
--- a/src/cmd/cc/cc1/init.c
+++ b/src/cmd/cc/cc1/init.c
@@ -138,14 +138,14 @@
static Node *
mkcompound(Init *ip, Type *tp)
{
- Node **v, **p;
+ Node **v, **p, *np;
size_t n;
struct designator *dp, *next;
Symbol *sym;
+ int isconst = 1;
if (tp->op == UNION) {
- Node *np = NULL;
-
+ np = NULL;
v = xmalloc(sizeof(*v));
for (dp = ip->head; dp; dp = next) {
freetree(np);
@@ -153,6 +153,8 @@
next = dp->next;
free(dp);
}
+ if ((np->flags & NCONST) == 0)
+ isconst = 0;
*v = np;
} else {
n = (tp->prop&TDEFINED) ? tp->n.elem : ip->max;
@@ -168,7 +170,10 @@
for (dp = ip->head; dp; dp = next) {
p = &v[dp->pos];
freetree(*p);
- *p = dp->expr;
+ np = dp->expr;
+ *p = np;
+ if ((np->flags & NCONST) == 0)
+ isconst = 0;
next = dp->next;
free(dp);
}
@@ -180,7 +185,7 @@
sym->type = tp;
sym->flags |= SINITLST;
- return constnode(sym);
+ return (isconst ? constnode : varnode)(sym);
}
static void
@@ -364,7 +369,7 @@
if (flags & SDEFINED) {
errorp("redeclaration of '%s'", sym->name);
} else if ((flags & (SGLOBAL|SLOCAL|SPRIVATE)) != 0) {
- if (!(np->flags & NCONST)) {
+ if ((np->flags & NCONST) == 0) {
errorp("initializer element is not constant");
return;
}