From b46efcde82436e73c73dab132f73aeff98673894 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 25 Feb 2020 12:22:21 +0100 Subject: ir: Fix sizeOf comparison with ptr to zst Closes #4536 --- src/analyze.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/analyze.cpp') diff --git a/src/analyze.cpp b/src/analyze.cpp index 95b2c77129..5ee5f44643 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -1132,10 +1132,9 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent 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->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) || - type_val->data.x_type->id == ZigTypeIdPointer) + type_val->data.x_type->data.unionation.resolve_loop_flag_zero_bits)) { // Does a struct/union which contains a pointer field to itself have bits? Yes. *is_zero_bits = false; -- cgit v1.2.3 From d2535c003c6188fcc362028e01ef9f7fb3356727 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 26 Feb 2020 10:05:04 +0100 Subject: ir: Fix regression with self-referencing containers --- src/analyze.cpp | 19 ++++++++++++++----- test/stage1/behavior/sizeof_and_typeof.zig | 22 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) (limited to 'src/analyze.cpp') diff --git a/src/analyze.cpp b/src/analyze.cpp index 5ee5f44643..41ae69f803 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -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; } diff --git a/test/stage1/behavior/sizeof_and_typeof.zig b/test/stage1/behavior/sizeof_and_typeof.zig index e3b62b15cc..322c5fbbad 100644 --- a/test/stage1/behavior/sizeof_and_typeof.zig +++ b/test/stage1/behavior/sizeof_and_typeof.zig @@ -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); } -- cgit v1.2.3