scc

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

commit a4c970a99941637b75f5fc42b45e9d774aff6d7d
parent 5f4055245f05a0f49f5633ce3eb55d786b0ce824
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed, 17 Nov 2021 07:50:09 +0100

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.

Diffstat:
Msrc/cmd/cc/cc1/fold.c | 4+++-
Msrc/cmd/cc/cc1/init.c | 17+++++++++++------
2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/src/cmd/cc/cc1/fold.c b/src/cmd/cc/cc1/fold.c @@ -454,8 +454,10 @@ fold(Node *np) 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: diff --git a/src/cmd/cc/cc1/init.c b/src/cmd/cc/cc1/init.c @@ -138,14 +138,14 @@ initialize(Type *tp) 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 @@ mkcompound(Init *ip, Type *tp) 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 @@ mkcompound(Init *ip, Type *tp) 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 @@ mkcompound(Init *ip, Type *tp) sym->type = tp; sym->flags |= SINITLST; - return constnode(sym); + return (isconst ? constnode : varnode)(sym); } static void @@ -364,7 +369,7 @@ initializer(Symbol *sym, Type *tp) 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; }