harec

[hare] Hare compiler, written in C11 for POSIX OSs
Log | Files | Refs | README | LICENSE

commit 444f9ae789ffc750f98b7ce512e5c3e7c1762f08
parent 251b8ac3485a3ec016a89fd8c78bec021e587f27
Author: Bor Grošelj Simić <bgs@turminal.net>
Date:   Sat, 27 Aug 2022 13:54:34 +0200

fix error reporting of non-type objects appearing in type contexts

Types that contained aliases sometimes crashed the compiler if their
members were actually not aliases but non-type objects. This is fixed by
adding a check for non-type objects into resolve_dimensions(). A similar
check already exists in the resolve_type() function.

Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>

Diffstat:
Msrc/check.c | 12++++++++++++
Mtests/34-declarations.ha | 40++++++++++++++++++++++++++++------------
2 files changed, 40 insertions(+), 12 deletions(-)

diff --git a/src/check.c b/src/check.c @@ -3825,7 +3825,19 @@ resolve_enum_alias(struct context *ctx, const struct scope_object *obj) const struct scope_object * resolve_dimensions(struct context *ctx, const struct scope_object *obj) { + assert(obj->otype == O_SCAN); struct incomplete_declaration *idecl = (struct incomplete_declaration*)obj; + if (idecl->type != IDECL_DECL || idecl->decl.decl_type != AST_DECL_TYPE) { + struct location loc; + if (idecl->type == IDECL_ENUM_FLD) { + loc = idecl->field->field->loc; + } else { + loc = idecl->decl.loc; + } + error(ctx, loc, false, "'%s' is not a type", + identifier_unparse(&idecl->obj.name)); + handle_errors(ctx->errors); + } struct dimensions dim = type_store_lookup_dimensions(ctx->store, idecl->decl.type.type); ((struct scope_object *)obj)->type = xcalloc(1, sizeof(struct type)); diff --git a/tests/34-declarations.ha b/tests/34-declarations.ha @@ -205,18 +205,34 @@ fn sz() void = { }; fn reject() void = { - // TODO: figure out a better way to test these - assert(compile("type a = b; type b = a;") as exited != EXIT_SUCCESS); - assert(compile("type a = [20]a;") as exited != EXIT_SUCCESS); - assert(compile("type a = b; type b = a;") as exited != EXIT_SUCCESS); - assert(compile("type a = [20]a;") as exited != EXIT_SUCCESS); - assert(compile("type a = unknown;") as exited != EXIT_SUCCESS); - assert(compile("def x: int = 6; type a = x;") as exited != EXIT_SUCCESS); - assert(compile("type a = int; type a = str;") as exited != EXIT_SUCCESS); - assert(compile("def a: int = b; def b: int = a;") as exited != EXIT_SUCCESS); - assert(compile("def x: size = size(t); type t = [x]int;") as exited != EXIT_SUCCESS); - assert(compile("def a: int = 12; type t = (int |(...a | a));") as exited != EXIT_SUCCESS); - assert(compile("def a: int = 12; type t = (int |(...a | a));") as exited != EXIT_SUCCESS); + let failures = [ + "type a = b; type b = a;", + "type a = [20]a;", + "type a = b; type b = a;", + "type a = [20]a;", + "type a = unknown;", + "def x: int = 6; type a = x;", + "type a = int; type a = str;", + "def a: int = b; def b: int = a;", + "def x: size = size(t); type t = [x]int;", + "def a: int = 12; type t = (int |(...a | a));", + "type a = (...unknown | int);", + + // usage of non-type aliases + "let a: int = 4; type x = a;", + "let a: int = 4; type x = *a;", + "let a: int = 4; type x = []a;", + "let a: int = 4; type x = [3]a;", + "let a: int = 4; type x = (str, a);", + "let a: int = 4; type x = (str | a);", + "let a: int = 4; type x = struct { y: str, z: a};", + "let a: int = 4; type x = union { y: str, z: a};", + "let a: int = 4; fn x(y: str, z: a) void = { void; };", + ]; + + for (let i = 0z; i < len(failures); i += 1) { + assert(compile(failures[i]) as exited != EXIT_SUCCESS); + }; }; // Types t_0 to t_9 form a complete directed graph on 10 vertices.