~sircmpwn/harec

edd7b87a5ab5d4d3d1bbde922734eea7181dc614 — Ember Sawady 2 months ago c8c81f3
type_init_from_atype: drop type_is_complete

fixes a bug with forward declarations of packed structs

Signed-off-by: Ember Sawady <ecs@d2evs.net>
4 files changed, 11 insertions(+), 23 deletions(-)

M include/types.h
M src/type_store.c
M src/types.c
M tests/26-regression.ha
M include/types.h => include/types.h +0 -1
@@ 192,7 192,6 @@ bool type_is_assignable(struct context *ctx,
	const struct type *to, const struct type *from);
const struct type *type_is_castable(struct context *ctx,
	const struct type *to, const struct type *from);
bool type_is_complete(const struct type *type);

const struct type *type_create_const(enum type_storage storage,
	int64_t min, int64_t max);

M src/type_store.c => src/type_store.c +5 -10
@@ 890,20 890,15 @@ type_init_from_atype(struct type_store *store,
		break;
	}

	bool packed = false;
	if (type_is_complete(type)) {
		const struct type *final = type_dealias(store->check_context, type);
		if (final->storage == STORAGE_STRUCT) {
			packed = final->struct_union.packed;
		}
	}

	struct dimensions dim = {
		.size = type->size,
		.align = type->align,
	};
	if (!packed) {
		add_padding(&dim.size, dim.align);
	if (type->storage != STORAGE_STRUCT || !type->struct_union.packed) {
		// padding an alias can only break packed structs
		if (type->storage != STORAGE_ALIAS) {
			add_padding(&dim.size, dim.align);
		};
	}
	return dim;
}

M src/types.c => src/types.c +0 -12
@@ 67,18 67,6 @@ type_dealias(struct context *ctx, const struct type *type)
	return type;
}

bool
type_is_complete(const struct type *type)
{
	while (type->storage == STORAGE_ALIAS) {
		if (type->alias.type == NULL) {
			return false;
		}
		type = type->alias.type;
	}
	return true;
}

const struct struct_field *
type_get_field(struct context *ctx, const struct type *type, const char *name)
{

M tests/26-regression.ha => tests/26-regression.ha +6 -0
@@ 26,6 26,10 @@ type b = struct { c: c };
type a = struct { b };
type c = *a;

// order of these two matters
let packedsz = size(packed);
type packed = struct @packed { a: u64, b: u8 };

type d = [3]int;
type e = bool;
let x = [1, 2, 3]: d: []int;


@@ 204,4 208,6 @@ export fn main() void = {
	assert(rt::compile(*(&buf: *str)) as rt::exited == rt::EXIT_SUCCESS);
	static insert(buf[n], rt::toutf8("::a")...);
	assert(rt::compile(*(&buf: *str)) as rt::exited != rt::EXIT_SUCCESS);
	assert(size(packed) == packedsz);
	assert(size(packed) == 9);
};