| author | |
| committer | |
| log | c4a2734aa08a9e810680d7be2c976fe3ae67cc5b |
| tree | 762fb4fe3e6a334f8845c0fb5ccffd685b65ebcb |
| parent | aa2aad229c96427f8b9130a3665a1f6ad768ec4c |
| parent | d2535c003c6188fcc362028e01ef9f7fb3356727 |
| signature |
Resend of #45522 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 |
| 1131 | 1131 | Error err; |
| 1132 | 1132 | if (type_val->special != ConstValSpecialLazy) { |
| 1133 | 1133 | 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)) | |
| 1139 | 1146 | { |
| 1140 | // Does a struct/union which contains a pointer field to itself have bits? Yes. | |
| 1141 | 1147 | *is_zero_bits = false; |
| 1142 | 1148 | return ErrorNone; |
| 1143 | 1149 | } |
| 1150 | ||
| 1144 | 1151 | if ((err = type_resolve(g, type_val->data.x_type, ResolveStatusZeroBitsKnown))) |
| 1145 | 1152 | return err; |
| 1153 | ||
| 1146 | 1154 | *is_zero_bits = (type_val->data.x_type->abi_size == 0); |
| 1147 | 1155 | return ErrorNone; |
| 1148 | 1156 | } |
test/stage1/behavior/sizeof_and_typeof.zig+54-2| ... | ... | @@ -1,5 +1,7 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const expect = @import("std").testing.expect; | |
| 1 | const std = @import("std"); | |
| 2 | const builtin = std.builtin; | |
| 3 | const expect = std.testing.expect; | |
| 4 | const expectEqual = std.testing.expectEqual; | |
| 3 | 5 | |
| 4 | 6 | test "@sizeOf and @TypeOf" { |
| 5 | 7 | const y: @TypeOf(x) = 120; |
| ... | ... | @@ -135,3 +137,53 @@ test "@bitSizeOf" { |
| 135 | 137 | a: u2 |
| 136 | 138 | }) == 2); |
| 137 | 139 | } |
| 140 | ||
| 141 | test "@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 | } |