commit a22f0c06a22868578215b1dc2897e297a5ee9121
parent 29cf8b8cf49e268392c15caed5f48ce0b71c8a39
Author: Eyal Sawady <ecs@d2evs.net>
Date: Tue, 5 Oct 2021 21:15:40 +0000
Fix type reduction
There were three issues, all of which were exposed by STORAGE_NULL's
value being changed in 1a0162835046c8030c80164e6be032332be1d0c9. The
first was that we were using `break` rather than `continue` when we
found a non-matching type while looking for nullable/non-nullable
pointers to consolidate. The change caused null to sort before `*int`
and `nullable *int`, causing this minimal reproduction to fail:
export fn main() void = {
let x = match (0u8: (u8 | u16 | u32)) {
case u8 =>
yield null: *int;
case u16 =>
yield null: nullable *int;
case u32 =>
yield null;
};
};
In addition to this, due to an incorrect usage of `&&` rather than `&`,
the const consolidation code was being run, exposing a bug in the linked
list traversal code causing a segfault.
Signed-off-by: Eyal Sawady <ecs@d2evs.net>
Diffstat:
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/src/type_store.c b/src/type_store.c
@@ -1025,17 +1025,20 @@ type_store_reduce_result(struct type_store *store, struct type_tagged_union *in)
bool dropped = false;
const struct type *it = i->type;
- if (it->flags && TYPE_CONST) {
- for (struct type_tagged_union **j = ∈ *j;
- j = &(*j)->next) {
+ if (it->flags & TYPE_CONST) {
+ struct type_tagged_union **j = ∈
+ while (*j) {
const struct type *jt = (*j)->type;
if (jt == it) {
+ j = &(*j)->next;
continue;
}
jt = type_store_lookup_with_flags(store, jt,
jt->flags | TYPE_CONST);
if (jt == it) {
*j = (*j)->next;
+ } else {
+ j = &(*j)->next;
}
}
}
@@ -1045,13 +1048,13 @@ type_store_reduce_result(struct type_store *store, struct type_tagged_union *in)
assert(it->id != jt->id);
if (it->storage != STORAGE_POINTER
|| jt->storage != STORAGE_POINTER) {
- break;
+ continue;
}
if (it->pointer.referent->id != jt->pointer.referent->id) {
- break;
+ continue;
}
if (it->flags != jt->flags) {
- break;
+ continue;
}
if ((it->pointer.flags & PTR_NULLABLE)
|| (jt->pointer.flags & PTR_NULLABLE)) {