authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-09-20 21:05:42+03:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-20 20:51:31-07:00
log55e7c099caa7cf8dc253dac21765bb994e06b741
tree8bca8b4f585bc0beb70e78346d704fbeb2b3eadd
parentd64d5cfc0a72a9989ed58548dd806a663f847ef5

stage2: various fixes to cImport, sizeOf and types to get tests passing


10 files changed, 304 insertions(+), 250 deletions(-)

src/AstGen.zig+2-3
...@@ -7082,7 +7082,7 @@ fn builtinCall(...@@ -7082,7 +7082,7 @@ fn builtinCall(
7082 .bit_cast => return bitCast( gz, scope, rl, node, params[0], params[1]),7082 .bit_cast => return bitCast( gz, scope, rl, node, params[0], params[1]),
7083 .TypeOf => return typeOf( gz, scope, rl, node, params),7083 .TypeOf => return typeOf( gz, scope, rl, node, params),
7084 .union_init => return unionInit(gz, scope, rl, node, params),7084 .union_init => return unionInit(gz, scope, rl, node, params),
7085 .c_import => return cImport( gz, scope, rl, node, params[0]),7085 .c_import => return cImport( gz, scope, node, params[0]),
70867086
7087 .@"export" => {7087 .@"export" => {
7088 const node_tags = tree.nodes.items(.tag);7088 const node_tags = tree.nodes.items(.tag);
...@@ -7692,7 +7692,6 @@ fn shiftOp(...@@ -7692,7 +7692,6 @@ fn shiftOp(
7692fn cImport(7692fn cImport(
7693 gz: *GenZir,7693 gz: *GenZir,
7694 scope: *Scope,7694 scope: *Scope,
7695 rl: ResultLoc,
7696 node: Ast.Node.Index,7695 node: Ast.Node.Index,
7697 body_node: Ast.Node.Index,7696 body_node: Ast.Node.Index,
7698) InnerError!Zir.Inst.Ref {7697) InnerError!Zir.Inst.Ref {
...@@ -7712,7 +7711,7 @@ fn cImport(...@@ -7712,7 +7711,7 @@ fn cImport(
7712 try block_scope.setBlockBody(block_inst);7711 try block_scope.setBlockBody(block_inst);
7713 try gz.instructions.append(gpa, block_inst);7712 try gz.instructions.append(gpa, block_inst);
77147713
7715 return rvalue(gz, rl, .void_value, node);7714 return indexToRef(block_inst);
7716}7715}
77177716
7718fn overflowArithmetic(7717fn overflowArithmetic(
src/Compilation.zig+1-1
...@@ -2644,7 +2644,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {...@@ -2644,7 +2644,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
26442644
2645 const dep_basename = std.fs.path.basename(out_dep_path);2645 const dep_basename = std.fs.path.basename(out_dep_path);
2646 try man.addDepFilePost(zig_cache_tmp_dir, dep_basename);2646 try man.addDepFilePost(zig_cache_tmp_dir, dep_basename);
2647 if (build_options.is_stage1) try comp.stage1_cache_manifest.addDepFilePost(zig_cache_tmp_dir, dep_basename);2647 if (build_options.is_stage1 and comp.bin_file.options.use_stage1) try comp.stage1_cache_manifest.addDepFilePost(zig_cache_tmp_dir, dep_basename);
26482648
2649 const digest = man.final();2649 const digest = man.final();
2650 const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });2650 const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });
src/Sema.zig+37-4
...@@ -2183,11 +2183,10 @@ fn zirCImport(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Com...@@ -2183,11 +2183,10 @@ fn zirCImport(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Com
2183 @import("clang.zig").Stage2ErrorMsg.delete(c_import_res.errors.ptr, c_import_res.errors.len);2183 @import("clang.zig").Stage2ErrorMsg.delete(c_import_res.errors.ptr, c_import_res.errors.len);
2184 return sema.mod.failWithOwnedErrorMsg(&child_block.base, msg);2184 return sema.mod.failWithOwnedErrorMsg(&child_block.base, msg);
2185 }2185 }
2186 const c_import_pkg = @import("Package.zig").createWithDir(2186 const c_import_pkg = @import("Package.zig").create(
2187 sema.gpa,2187 sema.gpa,
2188 sema.mod.comp.local_cache_directory,
2189 null,2188 null,
2190 std.fs.path.basename(c_import_res.out_zig_path),2189 c_import_res.out_zig_path,
2191 ) catch |err| switch (err) {2190 ) catch |err| switch (err) {
2192 error.OutOfMemory => return error.OutOfMemory,2191 error.OutOfMemory => return error.OutOfMemory,
2193 else => unreachable, // we pass null for root_src_dir_path2192 else => unreachable, // we pass null for root_src_dir_path
...@@ -2200,6 +2199,9 @@ fn zirCImport(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Com...@@ -2200,6 +2199,9 @@ fn zirCImport(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Com
2200 const result = sema.mod.importPkg(c_import_pkg) catch |err|2199 const result = sema.mod.importPkg(c_import_pkg) catch |err|
2201 return sema.mod.fail(&child_block.base, src, "C import failed: {s}", .{@errorName(err)});2200 return sema.mod.fail(&child_block.base, src, "C import failed: {s}", .{@errorName(err)});
22022201
2202 sema.mod.astGenFile(result.file) catch |err|
2203 return sema.mod.fail(&child_block.base, src, "C import failed: {s}", .{@errorName(err)});
2204
2203 try sema.mod.semaFile(result.file);2205 try sema.mod.semaFile(result.file);
2204 const file_root_decl = result.file.root_decl.?;2206 const file_root_decl = result.file.root_decl.?;
2205 try sema.mod.declareDeclDependency(sema.owner_decl, file_root_decl);2207 try sema.mod.declareDeclDependency(sema.owner_decl, file_root_decl);
...@@ -6467,10 +6469,41 @@ fn runtimeBoolCmp(...@@ -6467,10 +6469,41 @@ fn runtimeBoolCmp(
64676469
6468fn zirSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {6470fn zirSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
6469 const inst_data = sema.code.instructions.items(.data)[inst].un_node;6471 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
6472 const src = inst_data.src();
6470 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };6473 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
6471 const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);6474 const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);
6472 const target = sema.mod.getTarget();6475 const target = sema.mod.getTarget();
6473 const abi_size = operand_ty.abiSize(target);6476 const abi_size = switch (operand_ty.zigTypeTag()) {
6477 .Fn => unreachable,
6478 .NoReturn,
6479 .Undefined,
6480 .Null,
6481 .BoundFn,
6482 .Opaque,
6483 => return sema.mod.fail(&block.base, src, "no size available for type '{}'", .{operand_ty}),
6484 .Type,
6485 .EnumLiteral,
6486 .ComptimeFloat,
6487 .ComptimeInt,
6488 .Void,
6489 => 0,
6490
6491 .Bool,
6492 .Int,
6493 .Float,
6494 .Pointer,
6495 .Array,
6496 .Struct,
6497 .Optional,
6498 .ErrorUnion,
6499 .ErrorSet,
6500 .Enum,
6501 .Union,
6502 .Vector,
6503 .Frame,
6504 .AnyFrame,
6505 => operand_ty.abiSize(target),
6506 };
6474 return sema.addIntUnsigned(Type.initTag(.comptime_int), abi_size);6507 return sema.addIntUnsigned(Type.initTag(.comptime_int), abi_size);
6475}6508}
64766509
src/print_zir.zig+15-3
...@@ -407,15 +407,27 @@ const Writer = struct {...@@ -407,15 +407,27 @@ const Writer = struct {
407 .mul_with_saturation,407 .mul_with_saturation,
408 .shl_with_saturation,408 .shl_with_saturation,
409 => try self.writeSaturatingArithmetic(stream, extended),409 => try self.writeSaturatingArithmetic(stream, extended),
410
410 .struct_decl => try self.writeStructDecl(stream, extended),411 .struct_decl => try self.writeStructDecl(stream, extended),
411 .union_decl => try self.writeUnionDecl(stream, extended),412 .union_decl => try self.writeUnionDecl(stream, extended),
412 .enum_decl => try self.writeEnumDecl(stream, extended),413 .enum_decl => try self.writeEnumDecl(stream, extended),
413414
415 .c_undef, .c_include => {
416 const inst_data = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;
417 try self.writeInstRef(stream, inst_data.operand);
418 try stream.writeAll(") ");
419 },
420
421 .c_define => {
422 const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
423 try self.writeInstRef(stream, inst_data.lhs);
424 try stream.writeAll(", ");
425 try self.writeInstRef(stream, inst_data.rhs);
426 try stream.writeByte(')');
427 },
428
414 .alloc,429 .alloc,
415 .builtin_extern,430 .builtin_extern,
416 .c_undef,
417 .c_include,
418 .c_define,
419 .wasm_memory_size,431 .wasm_memory_size,
420 .wasm_memory_grow,432 .wasm_memory_grow,
421 => try stream.writeAll("TODO))"),433 => try stream.writeAll("TODO))"),
src/type.zig+1-1
...@@ -602,8 +602,8 @@ pub const Type = extern union {...@@ -602,8 +602,8 @@ pub const Type = extern union {
602 }602 }
603 return false;603 return false;
604 },604 },
605 .Float => return a.tag() == b.tag(),
605 .Opaque,606 .Opaque,
606 .Float,
607 .BoundFn,607 .BoundFn,
608 .Frame,608 .Frame,
609 => std.debug.panic("TODO implement Type equality comparison of {} and {}", .{ a, b }),609 => std.debug.panic("TODO implement Type equality comparison of {} and {}", .{ a, b }),
test/behavior.zig+4-2
...@@ -11,6 +11,8 @@ test {...@@ -11,6 +11,8 @@ test {
11 _ = @import("behavior/array.zig");11 _ = @import("behavior/array.zig");
12 _ = @import("behavior/usingnamespace.zig");12 _ = @import("behavior/usingnamespace.zig");
13 _ = @import("behavior/atomics.zig");13 _ = @import("behavior/atomics.zig");
14 _ = @import("behavior/sizeof_and_typeof.zig");
15 _ = @import("behavior/translate_c_macros.zig");
1416
15 if (builtin.zig_is_stage2) {17 if (builtin.zig_is_stage2) {
16 // When all comptime_memory.zig tests pass, #9646 can be closed.18 // When all comptime_memory.zig tests pass, #9646 can be closed.
...@@ -128,7 +130,7 @@ test {...@@ -128,7 +130,7 @@ test {
128 _ = @import("behavior/saturating_arithmetic.zig");130 _ = @import("behavior/saturating_arithmetic.zig");
129 _ = @import("behavior/shuffle.zig");131 _ = @import("behavior/shuffle.zig");
130 _ = @import("behavior/select.zig");132 _ = @import("behavior/select.zig");
131 _ = @import("behavior/sizeof_and_typeof.zig");133 _ = @import("behavior/sizeof_and_typeof_stage1.zig");
132 _ = @import("behavior/slice.zig");134 _ = @import("behavior/slice.zig");
133 _ = @import("behavior/slice_sentinel_comptime.zig");135 _ = @import("behavior/slice_sentinel_comptime.zig");
134 _ = @import("behavior/struct.zig");136 _ = @import("behavior/struct.zig");
...@@ -157,6 +159,6 @@ test {...@@ -157,6 +159,6 @@ test {
157 _ = @import("behavior/while.zig");159 _ = @import("behavior/while.zig");
158 _ = @import("behavior/widening.zig");160 _ = @import("behavior/widening.zig");
159 _ = @import("behavior/src.zig");161 _ = @import("behavior/src.zig");
160 _ = @import("behavior/translate_c_macros.zig");162 _ = @import("behavior/translate_c_macros_stage1.zig");
161 }163 }
162}164}
test/behavior/sizeof_and_typeof.zig-214
...@@ -10,118 +10,6 @@ test "@sizeOf and @TypeOf" {...@@ -10,118 +10,6 @@ test "@sizeOf and @TypeOf" {
10const x: u16 = 13;10const x: u16 = 13;
11const z: @TypeOf(x) = 19;11const z: @TypeOf(x) = 19;
1212
13const A = struct {
14 a: u8,
15 b: u32,
16 c: u8,
17 d: u3,
18 e: u5,
19 f: u16,
20 g: u16,
21 h: u9,
22 i: u7,
23};
24
25const P = packed struct {
26 a: u8,
27 b: u32,
28 c: u8,
29 d: u3,
30 e: u5,
31 f: u16,
32 g: u16,
33 h: u9,
34 i: u7,
35};
36
37test "@offsetOf" {
38 // Packed structs have fixed memory layout
39 try expect(@offsetOf(P, "a") == 0);
40 try expect(@offsetOf(P, "b") == 1);
41 try expect(@offsetOf(P, "c") == 5);
42 try expect(@offsetOf(P, "d") == 6);
43 try expect(@offsetOf(P, "e") == 6);
44 try expect(@offsetOf(P, "f") == 7);
45 try expect(@offsetOf(P, "g") == 9);
46 try expect(@offsetOf(P, "h") == 11);
47 try expect(@offsetOf(P, "i") == 12);
48
49 // Normal struct fields can be moved/padded
50 var a: A = undefined;
51 try expect(@ptrToInt(&a.a) - @ptrToInt(&a) == @offsetOf(A, "a"));
52 try expect(@ptrToInt(&a.b) - @ptrToInt(&a) == @offsetOf(A, "b"));
53 try expect(@ptrToInt(&a.c) - @ptrToInt(&a) == @offsetOf(A, "c"));
54 try expect(@ptrToInt(&a.d) - @ptrToInt(&a) == @offsetOf(A, "d"));
55 try expect(@ptrToInt(&a.e) - @ptrToInt(&a) == @offsetOf(A, "e"));
56 try expect(@ptrToInt(&a.f) - @ptrToInt(&a) == @offsetOf(A, "f"));
57 try expect(@ptrToInt(&a.g) - @ptrToInt(&a) == @offsetOf(A, "g"));
58 try expect(@ptrToInt(&a.h) - @ptrToInt(&a) == @offsetOf(A, "h"));
59 try expect(@ptrToInt(&a.i) - @ptrToInt(&a) == @offsetOf(A, "i"));
60}
61
62test "@offsetOf packed struct, array length not power of 2 or multiple of native pointer width in bytes" {
63 const p3a_len = 3;
64 const P3 = packed struct {
65 a: [p3a_len]u8,
66 b: usize,
67 };
68 try std.testing.expectEqual(0, @offsetOf(P3, "a"));
69 try std.testing.expectEqual(p3a_len, @offsetOf(P3, "b"));
70
71 const p5a_len = 5;
72 const P5 = packed struct {
73 a: [p5a_len]u8,
74 b: usize,
75 };
76 try std.testing.expectEqual(0, @offsetOf(P5, "a"));
77 try std.testing.expectEqual(p5a_len, @offsetOf(P5, "b"));
78
79 const p6a_len = 6;
80 const P6 = packed struct {
81 a: [p6a_len]u8,
82 b: usize,
83 };
84 try std.testing.expectEqual(0, @offsetOf(P6, "a"));
85 try std.testing.expectEqual(p6a_len, @offsetOf(P6, "b"));
86
87 const p7a_len = 7;
88 const P7 = packed struct {
89 a: [p7a_len]u8,
90 b: usize,
91 };
92 try std.testing.expectEqual(0, @offsetOf(P7, "a"));
93 try std.testing.expectEqual(p7a_len, @offsetOf(P7, "b"));
94
95 const p9a_len = 9;
96 const P9 = packed struct {
97 a: [p9a_len]u8,
98 b: usize,
99 };
100 try std.testing.expectEqual(0, @offsetOf(P9, "a"));
101 try std.testing.expectEqual(p9a_len, @offsetOf(P9, "b"));
102
103 // 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 25 etc. are further cases
104}
105
106test "@bitOffsetOf" {
107 // Packed structs have fixed memory layout
108 try expect(@bitOffsetOf(P, "a") == 0);
109 try expect(@bitOffsetOf(P, "b") == 8);
110 try expect(@bitOffsetOf(P, "c") == 40);
111 try expect(@bitOffsetOf(P, "d") == 48);
112 try expect(@bitOffsetOf(P, "e") == 51);
113 try expect(@bitOffsetOf(P, "f") == 56);
114 try expect(@bitOffsetOf(P, "g") == 72);
115
116 try expect(@offsetOf(A, "a") * 8 == @bitOffsetOf(A, "a"));
117 try expect(@offsetOf(A, "b") * 8 == @bitOffsetOf(A, "b"));
118 try expect(@offsetOf(A, "c") * 8 == @bitOffsetOf(A, "c"));
119 try expect(@offsetOf(A, "d") * 8 == @bitOffsetOf(A, "d"));
120 try expect(@offsetOf(A, "e") * 8 == @bitOffsetOf(A, "e"));
121 try expect(@offsetOf(A, "f") * 8 == @bitOffsetOf(A, "f"));
122 try expect(@offsetOf(A, "g") * 8 == @bitOffsetOf(A, "g"));
123}
124
125test "@sizeOf on compile-time types" {13test "@sizeOf on compile-time types" {
126 try expect(@sizeOf(comptime_int) == 0);14 try expect(@sizeOf(comptime_int) == 0);
127 try expect(@sizeOf(comptime_float) == 0);15 try expect(@sizeOf(comptime_float) == 0);
...@@ -129,34 +17,6 @@ test "@sizeOf on compile-time types" {...@@ -129,34 +17,6 @@ test "@sizeOf on compile-time types" {
129 try expect(@sizeOf(@TypeOf(type)) == 0);17 try expect(@sizeOf(@TypeOf(type)) == 0);
130}18}
13119
132test "@sizeOf(T) == 0 doesn't force resolving struct size" {
133 const S = struct {
134 const Foo = struct {
135 y: if (@sizeOf(Foo) == 0) u64 else u32,
136 };
137 const Bar = struct {
138 x: i32,
139 y: if (0 == @sizeOf(Bar)) u64 else u32,
140 };
141 };
142
143 try expect(@sizeOf(S.Foo) == 4);
144 try expect(@sizeOf(S.Bar) == 8);
145}
146
147test "@TypeOf() has no runtime side effects" {
148 const S = struct {
149 fn foo(comptime T: type, ptr: *T) T {
150 ptr.* += 1;
151 return ptr.*;
152 }
153 };
154 var data: i32 = 0;
155 const T = @TypeOf(S.foo(i32, &data));
156 comptime try expect(T == i32);
157 try expect(data == 0);
158}
159
160test "@TypeOf() with multiple arguments" {20test "@TypeOf() with multiple arguments" {
161 {21 {
162 var var_1: u32 = undefined;22 var var_1: u32 = undefined;
...@@ -180,19 +40,6 @@ test "@TypeOf() with multiple arguments" {...@@ -180,19 +40,6 @@ test "@TypeOf() with multiple arguments" {
180 }40 }
181}41}
18242
183test "branching logic inside @TypeOf" {
184 const S = struct {
185 var data: i32 = 0;
186 fn foo() anyerror!i32 {
187 data += 1;
188 return undefined;
189 }
190 };
191 const T = @TypeOf(S.foo() catch undefined);
192 comptime try expect(T == i32);
193 try expect(S.data == 0);
194}
195
196fn fn1(alpha: bool) void {43fn fn1(alpha: bool) void {
197 const n: usize = 7;44 const n: usize = 7;
198 _ = if (alpha) n else @sizeOf(usize);45 _ = if (alpha) n else @sizeOf(usize);
...@@ -201,64 +48,3 @@ fn fn1(alpha: bool) void {...@@ -201,64 +48,3 @@ fn fn1(alpha: bool) void {
201test "lazy @sizeOf result is checked for definedness" {48test "lazy @sizeOf result is checked for definedness" {
202 _ = fn1;49 _ = fn1;
203}50}
204
205test "@bitSizeOf" {
206 try expect(@bitSizeOf(u2) == 2);
207 try expect(@bitSizeOf(u8) == @sizeOf(u8) * 8);
208 try expect(@bitSizeOf(struct {
209 a: u2,
210 }) == 8);
211 try expect(@bitSizeOf(packed struct {
212 a: u2,
213 }) == 2);
214}
215
216test "@sizeOf comparison against zero" {
217 const S0 = struct {
218 f: *@This(),
219 };
220 const U0 = union {
221 f: *@This(),
222 };
223 const S1 = struct {
224 fn H(comptime T: type) type {
225 return struct {
226 x: T,
227 };
228 }
229 f0: H(*@This()),
230 f1: H(**@This()),
231 f2: H(***@This()),
232 };
233 const U1 = union {
234 fn H(comptime T: type) type {
235 return struct {
236 x: T,
237 };
238 }
239 f0: H(*@This()),
240 f1: H(**@This()),
241 f2: H(***@This()),
242 };
243 const S = struct {
244 fn doTheTest(comptime T: type, comptime result: bool) !void {
245 try expectEqual(result, @sizeOf(T) > 0);
246 }
247 };
248 // Zero-sized type
249 try S.doTheTest(u0, false);
250 try S.doTheTest(*u0, false);
251 // Non byte-sized type
252 try S.doTheTest(u1, true);
253 try S.doTheTest(*u1, true);
254 // Regular type
255 try S.doTheTest(u8, true);
256 try S.doTheTest(*u8, true);
257 try S.doTheTest(f32, true);
258 try S.doTheTest(*f32, true);
259 // Container with ptr pointing to themselves
260 try S.doTheTest(S0, true);
261 try S.doTheTest(U0, true);
262 try S.doTheTest(S1, true);
263 try S.doTheTest(U1, true);
264}
test/behavior/sizeof_and_typeof_stage1.zig created+218
...@@ -0,0 +1,218 @@
1const std = @import("std");
2const builtin = std.builtin;
3const expect = std.testing.expect;
4const expectEqual = std.testing.expectEqual;
5
6const A = struct {
7 a: u8,
8 b: u32,
9 c: u8,
10 d: u3,
11 e: u5,
12 f: u16,
13 g: u16,
14 h: u9,
15 i: u7,
16};
17
18const P = packed struct {
19 a: u8,
20 b: u32,
21 c: u8,
22 d: u3,
23 e: u5,
24 f: u16,
25 g: u16,
26 h: u9,
27 i: u7,
28};
29
30test "@offsetOf" {
31 // Packed structs have fixed memory layout
32 try expect(@offsetOf(P, "a") == 0);
33 try expect(@offsetOf(P, "b") == 1);
34 try expect(@offsetOf(P, "c") == 5);
35 try expect(@offsetOf(P, "d") == 6);
36 try expect(@offsetOf(P, "e") == 6);
37 try expect(@offsetOf(P, "f") == 7);
38 try expect(@offsetOf(P, "g") == 9);
39 try expect(@offsetOf(P, "h") == 11);
40 try expect(@offsetOf(P, "i") == 12);
41
42 // Normal struct fields can be moved/padded
43 var a: A = undefined;
44 try expect(@ptrToInt(&a.a) - @ptrToInt(&a) == @offsetOf(A, "a"));
45 try expect(@ptrToInt(&a.b) - @ptrToInt(&a) == @offsetOf(A, "b"));
46 try expect(@ptrToInt(&a.c) - @ptrToInt(&a) == @offsetOf(A, "c"));
47 try expect(@ptrToInt(&a.d) - @ptrToInt(&a) == @offsetOf(A, "d"));
48 try expect(@ptrToInt(&a.e) - @ptrToInt(&a) == @offsetOf(A, "e"));
49 try expect(@ptrToInt(&a.f) - @ptrToInt(&a) == @offsetOf(A, "f"));
50 try expect(@ptrToInt(&a.g) - @ptrToInt(&a) == @offsetOf(A, "g"));
51 try expect(@ptrToInt(&a.h) - @ptrToInt(&a) == @offsetOf(A, "h"));
52 try expect(@ptrToInt(&a.i) - @ptrToInt(&a) == @offsetOf(A, "i"));
53}
54
55test "@offsetOf packed struct, array length not power of 2 or multiple of native pointer width in bytes" {
56 const p3a_len = 3;
57 const P3 = packed struct {
58 a: [p3a_len]u8,
59 b: usize,
60 };
61 try std.testing.expectEqual(0, @offsetOf(P3, "a"));
62 try std.testing.expectEqual(p3a_len, @offsetOf(P3, "b"));
63
64 const p5a_len = 5;
65 const P5 = packed struct {
66 a: [p5a_len]u8,
67 b: usize,
68 };
69 try std.testing.expectEqual(0, @offsetOf(P5, "a"));
70 try std.testing.expectEqual(p5a_len, @offsetOf(P5, "b"));
71
72 const p6a_len = 6;
73 const P6 = packed struct {
74 a: [p6a_len]u8,
75 b: usize,
76 };
77 try std.testing.expectEqual(0, @offsetOf(P6, "a"));
78 try std.testing.expectEqual(p6a_len, @offsetOf(P6, "b"));
79
80 const p7a_len = 7;
81 const P7 = packed struct {
82 a: [p7a_len]u8,
83 b: usize,
84 };
85 try std.testing.expectEqual(0, @offsetOf(P7, "a"));
86 try std.testing.expectEqual(p7a_len, @offsetOf(P7, "b"));
87
88 const p9a_len = 9;
89 const P9 = packed struct {
90 a: [p9a_len]u8,
91 b: usize,
92 };
93 try std.testing.expectEqual(0, @offsetOf(P9, "a"));
94 try std.testing.expectEqual(p9a_len, @offsetOf(P9, "b"));
95
96 // 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 25 etc. are further cases
97}
98
99test "@bitOffsetOf" {
100 // Packed structs have fixed memory layout
101 try expect(@bitOffsetOf(P, "a") == 0);
102 try expect(@bitOffsetOf(P, "b") == 8);
103 try expect(@bitOffsetOf(P, "c") == 40);
104 try expect(@bitOffsetOf(P, "d") == 48);
105 try expect(@bitOffsetOf(P, "e") == 51);
106 try expect(@bitOffsetOf(P, "f") == 56);
107 try expect(@bitOffsetOf(P, "g") == 72);
108
109 try expect(@offsetOf(A, "a") * 8 == @bitOffsetOf(A, "a"));
110 try expect(@offsetOf(A, "b") * 8 == @bitOffsetOf(A, "b"));
111 try expect(@offsetOf(A, "c") * 8 == @bitOffsetOf(A, "c"));
112 try expect(@offsetOf(A, "d") * 8 == @bitOffsetOf(A, "d"));
113 try expect(@offsetOf(A, "e") * 8 == @bitOffsetOf(A, "e"));
114 try expect(@offsetOf(A, "f") * 8 == @bitOffsetOf(A, "f"));
115 try expect(@offsetOf(A, "g") * 8 == @bitOffsetOf(A, "g"));
116}
117
118test "@sizeOf(T) == 0 doesn't force resolving struct size" {
119 const S = struct {
120 const Foo = struct {
121 y: if (@sizeOf(Foo) == 0) u64 else u32,
122 };
123 const Bar = struct {
124 x: i32,
125 y: if (0 == @sizeOf(Bar)) u64 else u32,
126 };
127 };
128
129 try expect(@sizeOf(S.Foo) == 4);
130 try expect(@sizeOf(S.Bar) == 8);
131}
132
133test "@TypeOf() has no runtime side effects" {
134 const S = struct {
135 fn foo(comptime T: type, ptr: *T) T {
136 ptr.* += 1;
137 return ptr.*;
138 }
139 };
140 var data: i32 = 0;
141 const T = @TypeOf(S.foo(i32, &data));
142 comptime try expect(T == i32);
143 try expect(data == 0);
144}
145
146test "branching logic inside @TypeOf" {
147 const S = struct {
148 var data: i32 = 0;
149 fn foo() anyerror!i32 {
150 data += 1;
151 return undefined;
152 }
153 };
154 const T = @TypeOf(S.foo() catch undefined);
155 comptime try expect(T == i32);
156 try expect(S.data == 0);
157}
158
159test "@bitSizeOf" {
160 try expect(@bitSizeOf(u2) == 2);
161 try expect(@bitSizeOf(u8) == @sizeOf(u8) * 8);
162 try expect(@bitSizeOf(struct {
163 a: u2,
164 }) == 8);
165 try expect(@bitSizeOf(packed struct {
166 a: u2,
167 }) == 2);
168}
169
170test "@sizeOf comparison against zero" {
171 const S0 = struct {
172 f: *@This(),
173 };
174 const U0 = union {
175 f: *@This(),
176 };
177 const S1 = struct {
178 fn H(comptime T: type) type {
179 return struct {
180 x: T,
181 };
182 }
183 f0: H(*@This()),
184 f1: H(**@This()),
185 f2: H(***@This()),
186 };
187 const U1 = union {
188 fn H(comptime T: type) type {
189 return struct {
190 x: T,
191 };
192 }
193 f0: H(*@This()),
194 f1: H(**@This()),
195 f2: H(***@This()),
196 };
197 const S = struct {
198 fn doTheTest(comptime T: type, comptime result: bool) !void {
199 try expectEqual(result, @sizeOf(T) > 0);
200 }
201 };
202 // Zero-sized type
203 try S.doTheTest(u0, false);
204 try S.doTheTest(*u0, false);
205 // Non byte-sized type
206 try S.doTheTest(u1, true);
207 try S.doTheTest(*u1, true);
208 // Regular type
209 try S.doTheTest(u8, true);
210 try S.doTheTest(*u8, true);
211 try S.doTheTest(f32, true);
212 try S.doTheTest(*f32, true);
213 // Container with ptr pointing to themselves
214 try S.doTheTest(S0, true);
215 try S.doTheTest(U0, true);
216 try S.doTheTest(S1, true);
217 try S.doTheTest(U1, true);
218}
test/behavior/translate_c_macros.zig-22
...@@ -3,28 +3,6 @@ const expectEqual = @import("std").testing.expectEqual;...@@ -3,28 +3,6 @@ const expectEqual = @import("std").testing.expectEqual;
33
4const h = @cImport(@cInclude("behavior/translate_c_macros.h"));4const h = @cImport(@cInclude("behavior/translate_c_macros.h"));
55
6test "initializer list expression" {
7 try expectEqual(h.Color{
8 .r = 200,
9 .g = 200,
10 .b = 200,
11 .a = 255,
12 }, h.LIGHTGRAY);
13}
14
15test "sizeof in macros" {
16 try expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF(u32));
17 try expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF2(u32));
18}
19
20test "reference to a struct type" {
21 try expectEqual(@sizeOf(h.struct_Foo), h.SIZE_OF_FOO);
22}
23
24test "cast negative integer to pointer" {
25 try expectEqual(@intToPtr(?*c_void, @bitCast(usize, @as(isize, -1))), h.MAP_FAILED);
26}
27
28test "casting to void with a macro" {6test "casting to void with a macro" {
29 h.IGNORE_ME_1(42);7 h.IGNORE_ME_1(42);
30 h.IGNORE_ME_2(42);8 h.IGNORE_ME_2(42);
test/behavior/translate_c_macros_stage1.zig created+26
...@@ -0,0 +1,26 @@
1const expect = @import("std").testing.expect;
2const expectEqual = @import("std").testing.expectEqual;
3
4const h = @cImport(@cInclude("behavior/translate_c_macros.h"));
5
6test "initializer list expression" {
7 try expectEqual(h.Color{
8 .r = 200,
9 .g = 200,
10 .b = 200,
11 .a = 255,
12 }, h.LIGHTGRAY);
13}
14
15test "sizeof in macros" {
16 try expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF(u32));
17 try expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF2(u32));
18}
19
20test "reference to a struct type" {
21 try expectEqual(@sizeOf(h.struct_Foo), h.SIZE_OF_FOO);
22}
23
24test "cast negative integer to pointer" {
25 try expectEqual(@intToPtr(?*c_void, @bitCast(usize, @as(isize, -1))), h.MAP_FAILED);
26}