mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
ir: Fix regression with self-referencing containers
This commit is contained in:
parent
b46efcde82
commit
d2535c003c
@ -1131,17 +1131,26 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent
|
||||
Error err;
|
||||
if (type_val->special != ConstValSpecialLazy) {
|
||||
assert(type_val->special == ConstValSpecialStatic);
|
||||
if ((type_val->data.x_type->id == ZigTypeIdStruct &&
|
||||
type_val->data.x_type->data.structure.resolve_loop_flag_zero_bits) ||
|
||||
(type_val->data.x_type->id == ZigTypeIdUnion &&
|
||||
type_val->data.x_type->data.unionation.resolve_loop_flag_zero_bits))
|
||||
|
||||
// Self-referencing types via pointers are allowed and have non-zero size
|
||||
ZigType *ty = type_val->data.x_type;
|
||||
while (ty->id == ZigTypeIdPointer &&
|
||||
!ty->data.unionation.resolve_loop_flag_zero_bits)
|
||||
{
|
||||
ty = ty->data.pointer.child_type;
|
||||
}
|
||||
|
||||
if ((ty->id == ZigTypeIdStruct && ty->data.structure.resolve_loop_flag_zero_bits) ||
|
||||
(ty->id == ZigTypeIdUnion && ty->data.unionation.resolve_loop_flag_zero_bits) ||
|
||||
(ty->id == ZigTypeIdPointer && ty->data.pointer.resolve_loop_flag_zero_bits))
|
||||
{
|
||||
// Does a struct/union which contains a pointer field to itself have bits? Yes.
|
||||
*is_zero_bits = false;
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
if ((err = type_resolve(g, type_val->data.x_type, ResolveStatusZeroBitsKnown)))
|
||||
return err;
|
||||
|
||||
*is_zero_bits = (type_val->data.x_type->abi_size == 0);
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
@ -145,6 +145,26 @@ test "@sizeOf comparison against zero" {
|
||||
const U0 = union {
|
||||
f: *@This(),
|
||||
};
|
||||
const S1 = struct {
|
||||
fn H(comptime T: type) type {
|
||||
return struct {
|
||||
x: T,
|
||||
};
|
||||
}
|
||||
f0: H(*@This()),
|
||||
f1: H(**@This()),
|
||||
f2: H(***@This()),
|
||||
};
|
||||
const U1 = union {
|
||||
fn H(comptime T: type) type {
|
||||
return struct {
|
||||
x: T,
|
||||
};
|
||||
}
|
||||
f0: H(*@This()),
|
||||
f1: H(**@This()),
|
||||
f2: H(***@This()),
|
||||
};
|
||||
const S = struct {
|
||||
fn doTheTest(comptime T: type, comptime result: bool) void {
|
||||
expectEqual(result, @sizeOf(T) > 0);
|
||||
@ -164,4 +184,6 @@ test "@sizeOf comparison against zero" {
|
||||
// Container with ptr pointing to themselves
|
||||
S.doTheTest(S0, true);
|
||||
S.doTheTest(U0, true);
|
||||
S.doTheTest(S1, true);
|
||||
S.doTheTest(U1, true);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user