~sircmpwn/hare-dev

harec: fix error reporting of non-type objects appearing in type contexts v1 PROPOSED

Bor Grošelj Simić: 1
 fix error reporting of non-type objects appearing in type contexts

 3 files changed, 47 insertions(+), 12 deletions(-)
#786680 alpine.yml failed
#786681 freebsd.yml failed
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~sircmpwn/hare-dev/patches/33243/mbox | git am -3
Learn more about email & git

[PATCH harec] fix error reporting of non-type objects appearing in type contexts Export this patch

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().

Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>
---
 src/check.c              | 12 ++++++++++++
 tests/06-structs.ha      |  7 +++++++
 tests/34-declarations.ha | 40 ++++++++++++++++++++++++++++------------
 3 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/src/check.c b/src/check.c
index c6dd9a4..fe0b21e 100644
--- a/src/check.c
+++ b/src/check.c
@@ -3826,7 +3826,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/06-structs.ha b/tests/06-structs.ha
index ab78a54..486439b 100644
--- a/tests/06-structs.ha
+++ b/tests/06-structs.ha
@@ -167,6 +167,13 @@ fn invariants() void = {
	};
	",

	// embedding a non-alias type
	"type t = struct { int, x: int, a };",
	// embedding a non-struct alias
	"type a = str; type t = struct { int, x: int, a };",
	// embedding a non-type object
	"let a: int = 6; type t = struct { x: int, a };",

	// Duplicate members
	"fn test() void = { let x: struct { a: int, a: int } = struct { a: int = 2 };"
	// Dereference non-nullable pointer:
diff --git a/tests/34-declarations.ha b/tests/34-declarations.ha
index 111c8b3..98c7280 100644
--- 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(rt::compile("type a = b; type b = a;") == rt::EXIT_FAILURE);
	assert(rt::compile("type a = [20]a;") == rt::EXIT_FAILURE);
	assert(rt::compile("type a = b; type b = a;") == rt::EXIT_FAILURE);
	assert(rt::compile("type a = [20]a;") == rt::EXIT_FAILURE);
	assert(rt::compile("type a = unknown;") == rt::EXIT_FAILURE);
	assert(rt::compile("def x: int = 6; type a = x;") == rt::EXIT_FAILURE);
	assert(rt::compile("type a = int; type a = str;") == rt::EXIT_FAILURE);
	assert(rt::compile("def a: int = b; def b: int = a;") == rt::EXIT_FAILURE);
	assert(rt::compile("def x: size = size(t); type t = [x]int;") == rt::EXIT_FAILURE);
	assert(rt::compile("def a: int = 12; type t = (int |(...a | a));") == rt::EXIT_FAILURE);
	assert(rt::compile("type a = (...unknown | int);") == rt::EXIT_FAILURE);
	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(rt::compile(failures[i]) == rt::EXIT_FAILURE);
	};
};

// Types t_0 to t_9 form a complete directed graph on 10 vertices.
-- 
2.36.1
harec/patches: FAILED in 49s

[fix error reporting of non-type objects appearing in type contexts][0] from [Bor Grošelj Simić][1]

[0]: https://lists.sr.ht/~sircmpwn/hare-dev/patches/33243
[1]: mailto:bgs@turminal.net

✗ #786680 FAILED harec/patches/alpine.yml  https://builds.sr.ht/~sircmpwn/job/786680
✗ #786681 FAILED harec/patches/freebsd.yml https://builds.sr.ht/~sircmpwn/job/786681