diff options
author | Michael Forney <mforney@mforney.org> | 2024-04-07 13:15:31 -0700 |
---|---|---|
committer | Michael Forney <mforney@mforney.org> | 2024-04-07 13:29:14 -0700 |
commit | 1e66f1ce8a8df863042ab54ba6b68bd6d2e52396 (patch) | |
tree | 533189af89eaded53c3f204336d8cee4cd6fc281 | |
parent | bf28b11e50f287f1b32c4828b0ea1b5d9b9fd0e2 (diff) |
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
-rw-r--r-- | cc.h | 2 | ||||
-rw-r--r-- | decl.c | 26 | ||||
-rw-r--r-- | targ.c | 2 | ||||
-rw-r--r-- | type.c | 2 |
4 files changed, 19 insertions, 13 deletions
@@ -219,7 +219,7 @@ struct type { bool issigned, iscomplex; } basic; struct { - unsigned long long length; + struct expr *length; enum typequal ptrqual; } array; struct { @@ -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; @@ -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, }, @@ -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) { |