From 1e66f1ce8a8df863042ab54ba6b68bd6d2e52396 Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Sun, 7 Apr 2024 13:15:31 -0700 Subject: Store length expression in array types We don't need the length constant anymore, so just use that name for the length expression. References: https://todo.sr.ht/~mcf/cproc/1 --- cc.h | 2 +- decl.c | 26 ++++++++++++++++---------- targ.c | 2 +- type.c | 2 +- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/cc.h b/cc.h index d659872..068eb72 100644 --- a/cc.h +++ b/cc.h @@ -219,7 +219,7 @@ struct type { bool issigned, iscomplex; } basic; struct { - unsigned long long length; + struct expr *length; enum typequal ptrqual; } array; struct { diff --git a/decl.c b/decl.c index 2fb56c4..0075baf 100644 --- a/decl.c +++ b/decl.c @@ -542,7 +542,6 @@ declaratortypes(struct scope *s, struct list *result, char **name, bool allowabs struct type *t; struct param **p; struct expr *e; - unsigned long long i; enum typequal tq; bool allowattr; @@ -649,14 +648,10 @@ declaratortypes(struct scope *s, struct list *result, char **name, bool allowabs if (tok.kind == TMUL) error(&tok.loc, "VLAs are not yet supported"); if (tok.kind != TRBRACK) { - 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; - if (e->type->u.basic.issigned && i >> 63) - error(&tok.loc, "array length must be non-negative"); - delexpr(e); - t->u.array.length = i; + e = assignexpr(s); + if (!(e->type->prop & PROPINT)) + error(&tok.loc, "array length expression must have integer type"); + t->u.array.length = e; t->incomplete = false; } expect(TRBRACK, "after array length"); @@ -681,6 +676,7 @@ declarator(struct scope *s, struct qualtype base, char **name, bool allowabstrac { struct type *t; enum typequal tq; + struct expr *e; struct list result = {&result, &result}, *l, *prev; declaratortypes(s, &result, name, allowabstract); @@ -703,7 +699,17 @@ declarator(struct scope *s, struct qualtype base, char **name, bool allowabstrac if (base.type->kind == TYPEFUNC) error(&tok.loc, "array element has function type"); t->align = base.type->align; - t->size = base.type->size * t->u.array.length; /* XXX: overflow? */ + t->size = 0; + if (t->u.array.length) { + e = eval(t->u.array.length); + if (e->kind != EXPRCONST) + error(&tok.loc, "VLAs are not yet supported"); + if (e->type->u.basic.issigned && e->u.constant.u >> 63) + error(&tok.loc, "array length must be non-negative"); + if (e->u.constant.u > ULLONG_MAX / base.type->size) + error(&tok.loc, "array length is too large"); + t->size = base.type->size * e->u.constant.u; + } break; } base.type = t; diff --git a/targ.c b/targ.c index 9d0c179..b52c876 100644 --- a/targ.c +++ b/targ.c @@ -12,7 +12,7 @@ static const struct target alltargs[] = { .typevalist = &(struct type){ .kind = TYPEARRAY, .align = 8, .size = 24, - .u.array = {1}, .base = &(struct type){ + .base = &(struct type){ .kind = TYPESTRUCT, .align = 8, .size = 24, }, diff --git a/type.c b/type.c index 0aaff36..6798105 100644 --- a/type.c +++ b/type.c @@ -79,7 +79,7 @@ mkarraytype(struct type *base, enum typequal qual, unsigned long long len) t = mktype(TYPEARRAY, 0); t->base = base; t->qual = qual; - t->u.array.length = len; + t->u.array.length = NULL; t->u.array.ptrqual = QUALNONE; t->incomplete = !len; if (t->base) { -- cgit v1.2.3