authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-04 02:14:29-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-01-04 02:14:29-05:00
log5b0be0d436407bbb7a9c6445b6bc58347add301e
tree9b7be23684470f9753613d5143333bb057102367
parent6630a5ede5ee2e31386aab59761660952cca2e0e
parent0736d3077408ca15f1638024478f05ccce3635af
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #10499 from paulsnar/paulsnar/stage1-packed-structs-cabi

stage1: Fix LLVM C ABI type resolution for small packed structs

3 files changed, 126 insertions(+), 1 deletions(-)

src/stage1/analyze.cpp+1-1
......@@ -8962,7 +8962,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
89628962 struct_type->data.structure.llvm_full_type_queue_index = SIZE_MAX;
89638963 }
89648964
8965 if (struct_type->abi_size <= 16 && struct_type->data.structure.layout == ContainerLayoutExtern)
8965 if (struct_type->abi_size <= 16 && (struct_type->data.structure.layout == ContainerLayoutExtern || struct_type->data.structure.layout == ContainerLayoutPacked))
89668966 resolve_llvm_c_abi_type(g, struct_type);
89678967}
89688968
test/stage1/c_abi/cfuncs.c+66
......@@ -75,6 +75,24 @@ struct MedStructMixed {
7575void zig_med_struct_mixed(struct MedStructMixed);
7676struct MedStructMixed zig_ret_med_struct_mixed();
7777
78struct SmallPackedStruct {
79 uint8_t a: 2;
80 uint8_t b: 2;
81 uint8_t c: 2;
82 uint8_t d: 2;
83 uint8_t e: 1;
84};
85
86struct BigPackedStruct {
87 uint64_t a: 64;
88 uint64_t b: 64;
89 uint64_t c: 64;
90 uint64_t d: 64;
91 uint8_t e: 8;
92};
93
94//void zig_small_packed_struct(struct SmallPackedStruct); // #1481
95void zig_big_packed_struct(struct BigPackedStruct);
7896
7997struct SplitStructInts {
8098 uint64_t a;
......@@ -137,6 +155,16 @@ void run_c_tests(void) {
137155 zig_small_struct_ints(s);
138156 }
139157
158 {
159 struct BigPackedStruct s = {1, 2, 3, 4, 5};
160 zig_big_packed_struct(s);
161 }
162
163 {
164 struct SmallPackedStruct s = {0, 1, 2, 3, 1};
165 //zig_small_packed_struct(s);
166 }
167
140168 {
141169 struct SplitStructInts s = {1234, 100, 1337};
142170 zig_split_struct_ints(s);
......@@ -318,6 +346,44 @@ void c_split_struct_mixed(struct SplitStructMixed x) {
318346 assert_or_panic(y.c == 1337.0f);
319347}
320348
349struct SmallPackedStruct c_ret_small_packed_struct() {
350 struct SmallPackedStruct s = {
351 .a = 0,
352 .b = 1,
353 .c = 2,
354 .d = 3,
355 .e = 1,
356 };
357 return s;
358}
359
360void c_small_packed_struct(struct SmallPackedStruct x) {
361 assert_or_panic(x.a == 0);
362 assert_or_panic(x.a == 1);
363 assert_or_panic(x.a == 2);
364 assert_or_panic(x.a == 3);
365 assert_or_panic(x.e == 1);
366}
367
368struct BigPackedStruct c_ret_big_packed_struct() {
369 struct BigPackedStruct s = {
370 .a = 1,
371 .b = 2,
372 .c = 3,
373 .d = 4,
374 .e = 5,
375 };
376 return s;
377}
378
379void c_big_packed_struct(struct BigPackedStruct x) {
380 assert_or_panic(x.a == 1);
381 assert_or_panic(x.b == 2);
382 assert_or_panic(x.c == 3);
383 assert_or_panic(x.d == 4);
384 assert_or_panic(x.e == 5);
385}
386
321387struct SplitStructMixed c_ret_split_struct_mixed() {
322388 struct SplitStructMixed s = {
323389 .a = 1234,
test/stage1/c_abi/main.zig+59
......@@ -230,6 +230,65 @@ export fn zig_small_struct_ints(x: SmallStructInts) void {
230230 expect(x.d == 4) catch @panic("test failure");
231231}
232232
233const SmallPackedStruct = packed struct {
234 a: u2,
235 b: u2,
236 c: u2,
237 d: u2,
238 e: bool,
239};
240const c_small_packed_struct: fn (SmallPackedStruct) callconv(.C) void = @compileError("TODO: #1481");
241extern fn c_ret_small_packed_struct() SmallPackedStruct;
242
243// waiting on #1481
244//export fn zig_small_packed_struct(x: SmallPackedStruct) void {
245// expect(x.a == 0) catch @panic("test failure");
246// expect(x.b == 1) catch @panic("test failure");
247// expect(x.c == 2) catch @panic("test failure");
248// expect(x.d == 3) catch @panic("test failure");
249// expect(x.e) catch @panic("test failure");
250//}
251
252test "C ABI small packed struct" {
253 var s = SmallPackedStruct{ .a = 0, .b = 1, .c = 2, .d = 3, .e = true };
254 _ = s; //c_small_packed_struct(s); // waiting on #1481
255 var s2 = c_ret_small_packed_struct();
256 try expect(s2.a == 0);
257 try expect(s2.b == 1);
258 try expect(s2.c == 2);
259 try expect(s2.d == 3);
260 try expect(s2.e);
261}
262
263const BigPackedStruct = packed struct {
264 a: u64,
265 b: u64,
266 c: u64,
267 d: u64,
268 e: u8,
269};
270extern fn c_big_packed_struct(BigPackedStruct) void;
271extern fn c_ret_big_packed_struct() BigPackedStruct;
272
273export fn zig_big_packed_struct(x: BigPackedStruct) void {
274 expect(x.a == 1) catch @panic("test failure");
275 expect(x.b == 2) catch @panic("test failure");
276 expect(x.c == 3) catch @panic("test failure");
277 expect(x.d == 4) catch @panic("test failure");
278 expect(x.e == 5) catch @panic("test failure");
279}
280
281test "C ABI big packed struct" {
282 var s = BigPackedStruct{ .a = 1, .b = 2, .c = 3, .d = 4, .e = 5 };
283 c_big_packed_struct(s);
284 var s2 = c_ret_big_packed_struct();
285 try expect(s2.a == 1);
286 try expect(s2.b == 2);
287 try expect(s2.c == 3);
288 try expect(s2.d == 4);
289 try expect(s2.e == 5);
290}
291
233292const SplitStructInt = extern struct {
234293 a: u64,
235294 b: u8,