summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eval.c1
-rw-r--r--test.toc14
-rw-r--r--types.c9
3 files changed, 21 insertions, 3 deletions
diff --git a/eval.c b/eval.c
index 04ecdc9..f91ef0b 100644
--- a/eval.c
+++ b/eval.c
@@ -1021,6 +1021,7 @@ static Status eval_ident(Evaluator *ev, Identifier ident, Value *v, Location whe
}
Declaration *d = ident->decl;
if ((d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_TYPE && d->expr.typeval->kind == TYPE_STRUCT) {
+ // necessary for circularly-dependent structs
v->type = allocr_malloc(ev->allocr, sizeof *v->type);
v->type->flags = TYPE_IS_RESOLVED;
v->type->kind = TYPE_STRUCT;
diff --git a/test.toc b/test.toc
index 5fcc2a5..a47bab6 100644
--- a/test.toc
+++ b/test.toc
@@ -1,7 +1,20 @@
+main ::= fn() {
+ x: &a;
+ k := x.foo;
+}
+main();
#include "std/io.toc";
+a ::= struct {
+ foo: File;
+}
+
+
+/*
+
#include "std/io.toc", io;
#include "std/types.toc";
+
write_type ::= fn(f : &File, t :: Type) {
k ::= t._kind;
use TypeKind;
@@ -168,3 +181,4 @@ main();
Point2D ::= struct(t :: Type) {
x, y : t;
}
+*/
diff --git a/types.c b/types.c
index a196323..a4e41d3 100644
--- a/types.c
+++ b/types.c
@@ -263,6 +263,7 @@ static size_t compiler_alignof(Type *t) {
}
// size of a type at compile time
+// returns a value >= SIZE_MAX-1 if something goes wrong
static size_t compiler_sizeof(Type *t) {
Value v;
assert(t->flags & TYPE_IS_RESOLVED);
@@ -273,14 +274,16 @@ static size_t compiler_sizeof(Type *t) {
return sizeof v.fn;
case TYPE_PTR:
return sizeof v.ptr;
- case TYPE_ARR:
- return (size_t)t->arr->n * compiler_sizeof(t->arr->of);
+ case TYPE_ARR: {
+ size_t of_size = compiler_sizeof(t->arr->of);
+ if (of_size >= SIZE_MAX-1) return of_size;
+ return (size_t)t->arr->n * of_size;
+ }
case TYPE_TUPLE:
return sizeof v.tuple;
case TYPE_SLICE:
return sizeof v.slice;
case TYPE_STRUCT: {
- // these two ifs are purely for struct_resolve, so that it can detect use of future structs in a non-pointery way
if (t->struc->flags & STRUCT_DEF_RESOLVING)
return SIZE_MAX-1;
if (!(t->struc->flags & STRUCT_DEF_RESOLVED))