authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-26 11:11:28-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-02-26 11:11:28-05:00
logc4a2734aa08a9e810680d7be2c976fe3ae67cc5b
tree762fb4fe3e6a334f8845c0fb5ccffd685b65ebcb
parentaa2aad229c96427f8b9130a3665a1f6ad768ec4c
parentd2535c003c6188fcc362028e01ef9f7fb3356727
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #4561 from LemonBoy/fix-4536-1

Resend of #4552

2 files changed, 68 insertions(+), 8 deletions(-)

src/analyze.cpp+14-6
......@@ -1131,18 +1131,26 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent
11311131 Error err;
11321132 if (type_val->special != ConstValSpecialLazy) {
11331133 assert(type_val->special == ConstValSpecialStatic);
1134 if ((type_val->data.x_type->id == ZigTypeIdStruct &&
1135 type_val->data.x_type->data.structure.resolve_loop_flag_zero_bits) ||
1136 (type_val->data.x_type->id == ZigTypeIdUnion &&
1137 type_val->data.x_type->data.unionation.resolve_loop_flag_zero_bits) ||
1138 type_val->data.x_type->id == ZigTypeIdPointer)
1134
1135 // Self-referencing types via pointers are allowed and have non-zero size
1136 ZigType *ty = type_val->data.x_type;
1137 while (ty->id == ZigTypeIdPointer &&
1138 !ty->data.unionation.resolve_loop_flag_zero_bits)
1139 {
1140 ty = ty->data.pointer.child_type;
1141 }
1142
1143 if ((ty->id == ZigTypeIdStruct && ty->data.structure.resolve_loop_flag_zero_bits) ||
1144 (ty->id == ZigTypeIdUnion && ty->data.unionation.resolve_loop_flag_zero_bits) ||
1145 (ty->id == ZigTypeIdPointer && ty->data.pointer.resolve_loop_flag_zero_bits))
11391146 {
1140 // Does a struct/union which contains a pointer field to itself have bits? Yes.
11411147 *is_zero_bits = false;
11421148 return ErrorNone;
11431149 }
1150
11441151 if ((err = type_resolve(g, type_val->data.x_type, ResolveStatusZeroBitsKnown)))
11451152 return err;
1153
11461154 *is_zero_bits = (type_val->data.x_type->abi_size == 0);
11471155 return ErrorNone;
11481156 }
test/stage1/behavior/sizeof_and_typeof.zig+54-2
......@@ -1,5 +1,7 @@
1const builtin = @import("builtin");
2const expect = @import("std").testing.expect;
1const std = @import("std");
2const builtin = std.builtin;
3const expect = std.testing.expect;
4const expectEqual = std.testing.expectEqual;
35
46test "@sizeOf and @TypeOf" {
57 const y: @TypeOf(x) = 120;
......@@ -135,3 +137,53 @@ test "@bitSizeOf" {
135137 a: u2
136138 }) == 2);
137139}
140
141test "@sizeOf comparison against zero" {
142 const S0 = struct {
143 f: *@This(),
144 };
145 const U0 = union {
146 f: *@This(),
147 };
148 const S1 = struct {
149 fn H(comptime T: type) type {
150 return struct {
151 x: T,
152 };
153 }
154 f0: H(*@This()),
155 f1: H(**@This()),
156 f2: H(***@This()),
157 };
158 const U1 = union {
159 fn H(comptime T: type) type {
160 return struct {
161 x: T,
162 };
163 }
164 f0: H(*@This()),
165 f1: H(**@This()),
166 f2: H(***@This()),
167 };
168 const S = struct {
169 fn doTheTest(comptime T: type, comptime result: bool) void {
170 expectEqual(result, @sizeOf(T) > 0);
171 }
172 };
173 // Zero-sized type
174 S.doTheTest(u0, false);
175 S.doTheTest(*u0, false);
176 // Non byte-sized type
177 S.doTheTest(u1, true);
178 S.doTheTest(*u1, true);
179 // Regular type
180 S.doTheTest(u8, true);
181 S.doTheTest(*u8, true);
182 S.doTheTest(f32, true);
183 S.doTheTest(*f32, true);
184 // Container with ptr pointing to themselves
185 S.doTheTest(S0, true);
186 S.doTheTest(U0, true);
187 S.doTheTest(S1, true);
188 S.doTheTest(U1, true);
189}