shithub: scc

Download patch

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