authorgravatar for alex_naskos@hotmail.comAlexandros Naskos <alex_naskos@hotmail.com> 2020-11-16 09:12:42+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-11-16 09:12:42+02:00
log6e2e747b0b75cab59ac37cb3aff88f4e20c6448b
treedce760e22874a954c95606e2ec256139b74d68a9
parent7b9af0592de9041b18582ddf68b2d05adb2df977
parent7ebbc717c01ca46486a6a3447f9152fde7c5166e
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #7112 from LemonBoy/fix-7104

stage1: Fix generation of pass-by-value args in async fns

2 files changed, 33 insertions(+), 1 deletions(-)

src/stage1/codegen.cpp+3-1
...@@ -4411,8 +4411,10 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn...@@ -4411,8 +4411,10 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
4411 arg_calc = arg_calc_start;4411 arg_calc = arg_calc_start;
4412 for (size_t arg_i = 0; arg_i < gen_param_values.length; arg_i += 1) {4412 for (size_t arg_i = 0; arg_i < gen_param_values.length; arg_i += 1) {
4413 CalcLLVMFieldIndex prev = arg_calc;4413 CalcLLVMFieldIndex prev = arg_calc;
4414 // Use the declared argument type and not the value one to be
4415 // consistent with the assignment operation below.
4414 calc_llvm_field_index_add(g, &arg_calc, gen_param_types.at(arg_i));4416 calc_llvm_field_index_add(g, &arg_calc, gen_param_types.at(arg_i));
4415 field_types[arg_calc.field_index - 1] = LLVMTypeOf(gen_param_values.at(arg_i));4417 field_types[arg_calc.field_index - 1] = get_llvm_type(g, gen_param_types.at(arg_i));
4416 if (arg_calc.field_index - prev.field_index > 1) {4418 if (arg_calc.field_index - prev.field_index > 1) {
4417 // Padding field4419 // Padding field
4418 uint32_t pad_bytes = arg_calc.offset - prev.offset - gen_param_types.at(arg_i)->abi_size;4420 uint32_t pad_bytes = arg_calc.offset - prev.offset - gen_param_types.at(arg_i)->abi_size;
test/stage1/behavior/async_fn.zig+30
...@@ -1559,3 +1559,33 @@ test "avoid forcing frame alignment resolution implicit cast to *c_void" {...@@ -1559,3 +1559,33 @@ test "avoid forcing frame alignment resolution implicit cast to *c_void" {
1559 resume @ptrCast(anyframe->bool, @alignCast(@alignOf(@Frame(S.foo)), S.x));1559 resume @ptrCast(anyframe->bool, @alignCast(@alignOf(@Frame(S.foo)), S.x));
1560 expect(nosuspend await frame);1560 expect(nosuspend await frame);
1561}1561}
1562
1563test "@asyncCall with pass-by-value arguments" {
1564 const F0: u64 = 0xbeefbeefbeefbeef;
1565 const F1: u64 = 0xf00df00df00df00d;
1566 const F2: u64 = 0xcafecafecafecafe;
1567
1568 const S = struct {
1569 pub const ST = struct { f0: usize, f1: usize };
1570 pub const AT = [5]u8;
1571
1572 pub fn f(_fill0: u64, s: ST, _fill1: u64, a: AT, _fill2: u64) callconv(.Async) void {
1573 // Check that the array and struct arguments passed by value don't
1574 // end up overflowing the adjacent fields in the frame structure.
1575 expectEqual(F0, _fill0);
1576 expectEqual(F1, _fill1);
1577 expectEqual(F2, _fill2);
1578 }
1579 };
1580
1581 var buffer: [1024]u8 align(@alignOf(@Frame(S.f))) = undefined;
1582 // The function pointer must not be comptime-known.
1583 var t = S.f;
1584 var frame_ptr = @asyncCall(&buffer, {}, t, .{
1585 F0,
1586 .{ .f0 = 1, .f1 = 2 },
1587 F1,
1588 [_]u8{ 1, 2, 3, 4, 5 },
1589 F2,
1590 });
1591}