aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2024-04-07 13:15:31 -0700
committerMichael Forney <mforney@mforney.org>2024-04-07 13:29:14 -0700
commit1e66f1ce8a8df863042ab54ba6b68bd6d2e52396 (patch)
tree533189af89eaded53c3f204336d8cee4cd6fc281
parentbf28b11e50f287f1b32c4828b0ea1b5d9b9fd0e2 (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.h2
-rw-r--r--decl.c26
-rw-r--r--targ.c2
-rw-r--r--type.c2
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) {