diff options
-rw-r--r-- | eval.c | 1 | ||||
-rw-r--r-- | test.toc | 14 | ||||
-rw-r--r-- | types.c | 9 |
3 files changed, 21 insertions, 3 deletions
@@ -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; @@ -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; } +*/ @@ -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)) |