diff options
author | Michael Forney <mforney@mforney.org> | 2024-03-23 14:15:00 -0700 |
---|---|---|
committer | Michael Forney <mforney@mforney.org> | 2024-03-23 14:15:00 -0700 |
commit | 2e3ecc7000138622a528eef7681bfdd8ca0bc3c5 (patch) | |
tree | 86331119dbf3a15df98ea54701cedd6a8be63026 | |
parent | 52d9d1e21c38d33a0dcab8021751743ac180766b (diff) |
expr: Keep track of storage duration of compound literals
-rw-r--r-- | cc.h | 14 | ||||
-rw-r--r-- | decl.c | 2 | ||||
-rw-r--r-- | eval.c | 16 | ||||
-rw-r--r-- | expr.c | 15 | ||||
-rw-r--r-- | qbe.c | 2 |
5 files changed, 25 insertions, 24 deletions
@@ -247,6 +247,12 @@ enum linkage { LINKEXTERN, }; +enum storageduration { + SDSTATIC, + SDTHREAD, + SDAUTO, +}; + enum builtinkind { BUILTINALLOCA, BUILTINCONSTANTP, @@ -360,6 +366,7 @@ struct expr { struct bitfield bits; } bitfield; struct { + enum storageduration storage; struct init *init; } compound; struct { @@ -502,12 +509,7 @@ struct expr *exprpromote(struct expr *); /* eval */ -enum evalkind { - EVALARITH, /* arithmetic constant expression */ - EVALINIT, /* initializer constant expression */ -}; - -struct expr *eval(struct expr *, enum evalkind); +struct expr *eval(struct expr *); /* init */ @@ -625,7 +625,7 @@ declaratortypes(struct scope *s, struct list *result, char **name, bool allowabs error(&tok.loc, "VLAs are not yet supported"); t = mkarraytype(NULL, tq, 0); if (tok.kind != TRBRACK) { - e = eval(assignexpr(s), EVALARITH); + e = eval(assignexpr(s)); if (e->kind != EXPRCONST || !(e->type->prop & PROPINT)) error(&tok.loc, "VLAs are not yet supported"); i = e->u.constant.u; @@ -101,7 +101,7 @@ binary(struct expr *expr, enum tokenkind op, struct expr *l, struct expr *r) #undef S struct expr * -eval(struct expr *expr, enum evalkind kind) +eval(struct expr *expr) { struct expr *l, *r, *c; struct decl *d; @@ -116,7 +116,7 @@ eval(struct expr *expr, enum evalkind kind) expr->u.constant.u = intconstvalue(expr->u.ident.decl->value); break; case EXPRCOMPOUND: - if (kind != EVALINIT) + if (expr->u.compound.storage != SDSTATIC) break; d = mkdecl(DECLOBJECT, t, expr->qual, LINKNONE); d->value = mkglobal(NULL, true); @@ -125,17 +125,15 @@ eval(struct expr *expr, enum evalkind kind) expr->u.ident.decl = d; break; case EXPRUNARY: - l = eval(expr->base, kind); + l = eval(expr->base); switch (expr->op) { case TBAND: switch (l->kind) { case EXPRUNARY: if (l->op == TMUL) - expr = eval(l->base, kind); + expr = eval(l->base); break; case EXPRSTRING: - if (kind != EVALINIT) - break; l->u.ident.decl = stringdecl(l); l->kind = EXPRIDENT; expr->base = l; @@ -152,7 +150,7 @@ eval(struct expr *expr, enum evalkind kind) } break; case EXPRCAST: - l = eval(expr->base, kind); + l = eval(expr->base); if (l->kind == EXPRCONST) { expr->kind = EXPRCONST; if (l->type->prop & PROPINT && t->prop & PROPFLOAT) { @@ -186,8 +184,8 @@ eval(struct expr *expr, enum evalkind kind) } break; case EXPRBINARY: - l = eval(expr->u.binary.l, kind); - r = eval(expr->u.binary.r, kind); + l = eval(expr->u.binary.l); + r = eval(expr->u.binary.r); expr->u.binary.l = l; expr->u.binary.r = r; switch (expr->op) { @@ -271,11 +271,11 @@ mkbinaryexpr(struct location *loc, enum tokenkind op, struct expr *l, struct exp e = l, l = r, r = e; if (l->type->kind != TYPEPOINTER) error(loc, "invalid operands to '%s' operator", tokstr[op]); - if (nullpointer(eval(r, EVALARITH))) { + if (nullpointer(eval(r))) { r = exprconvert(r, l->type); break; } - if (nullpointer(eval(l, EVALARITH))) { + if (nullpointer(eval(l))) { l = exprconvert(l, r->type); break; } @@ -781,7 +781,7 @@ builtinfunc(struct scope *s, enum builtinkind kind) e->u.builtin.kind = BUILTINALLOCA; break; case BUILTINCONSTANTP: - e = mkconstexpr(&typeint, eval(condexpr(s), EVALARITH)->kind == EXPRCONST); + e = mkconstexpr(&typeint, eval(condexpr(s))->kind == EXPRCONST); break; case BUILTINEXPECT: /* just a no-op for now */ @@ -1126,6 +1126,7 @@ castexpr(struct scope *s) e->qual = tq; e->lvalue = true; e->u.compound.init = parseinit(s, t); + e->u.compound.storage = s == &filescope ? SDSTATIC : SDAUTO; e = postfixexpr(s, decay(e)); goto done; } @@ -1216,8 +1217,8 @@ condexpr(struct scope *s) } else if (lt == &typevoid && rt == &typevoid) { t = &typevoid; } else { - l = eval(l, EVALARITH); - r = eval(r, EVALARITH); + l = eval(l); + r = eval(r); if (nullpointer(l) && rt->kind == TYPEPOINTER) { t = rt; } else if (nullpointer(r) && lt->kind == TYPEPOINTER) { @@ -1239,7 +1240,7 @@ condexpr(struct scope *s) error(&tok.loc, "invalid operands to conditional operator"); } } - e = eval(e, EVALARITH); + e = eval(e); if (e->kind == EXPRCONST && e->type->prop & PROPINT) return exprconvert(e->u.constant.u ? l : r, t); e = mkexpr(EXPRCOND, t, e); @@ -1251,7 +1252,7 @@ condexpr(struct scope *s) struct expr * evalexpr(struct scope *s) { - return eval(condexpr(s), EVALARITH); + return eval(condexpr(s)); } unsigned long long @@ -1323,7 +1323,7 @@ emitdata(struct decl *d, struct init *init) align = d->u.obj.align; for (cur = init; cur; cur = cur->next) - cur->expr = eval(cur->expr, EVALINIT); + cur->expr = eval(cur->expr); if (d->linkage == LINKEXTERN) fputs("export ", stdout); fputs("data ", stdout); |