zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 6e2e747b0b75cab59ac37cb3aff88f4e20c6448b (tree)
parent 7b9af0592de9041b18582ddf68b2d05adb2df977
Author: Alexandros Naskos <alex_naskos@hotmail.com>
Date:   Mon, 16 Nov 2020 09:12:42 +0200

Merge pull request #7112 from LemonBoy/fix-7104

stage1: Fix generation of pass-by-value args in async fns
Diffstat:
Msrc/stage1/codegen.cpp | 4+++-
Mtest/stage1/behavior/async_fn.zig | 30++++++++++++++++++++++++++++++
2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp @@ -4411,8 +4411,10 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn arg_calc = arg_calc_start; for (size_t arg_i = 0; arg_i < gen_param_values.length; arg_i += 1) { CalcLLVMFieldIndex prev = arg_calc; + // Use the declared argument type and not the value one to be + // consistent with the assignment operation below. calc_llvm_field_index_add(g, &arg_calc, gen_param_types.at(arg_i)); - field_types[arg_calc.field_index - 1] = LLVMTypeOf(gen_param_values.at(arg_i)); + field_types[arg_calc.field_index - 1] = get_llvm_type(g, gen_param_types.at(arg_i)); if (arg_calc.field_index - prev.field_index > 1) { // Padding field uint32_t pad_bytes = arg_calc.offset - prev.offset - gen_param_types.at(arg_i)->abi_size; diff --git a/test/stage1/behavior/async_fn.zig b/test/stage1/behavior/async_fn.zig @@ -1559,3 +1559,33 @@ test "avoid forcing frame alignment resolution implicit cast to *c_void" { resume @ptrCast(anyframe->bool, @alignCast(@alignOf(@Frame(S.foo)), S.x)); expect(nosuspend await frame); } + +test "@asyncCall with pass-by-value arguments" { + const F0: u64 = 0xbeefbeefbeefbeef; + const F1: u64 = 0xf00df00df00df00d; + const F2: u64 = 0xcafecafecafecafe; + + const S = struct { + pub const ST = struct { f0: usize, f1: usize }; + pub const AT = [5]u8; + + pub fn f(_fill0: u64, s: ST, _fill1: u64, a: AT, _fill2: u64) callconv(.Async) void { + // Check that the array and struct arguments passed by value don't + // end up overflowing the adjacent fields in the frame structure. + expectEqual(F0, _fill0); + expectEqual(F1, _fill1); + expectEqual(F2, _fill2); + } + }; + + var buffer: [1024]u8 align(@alignOf(@Frame(S.f))) = undefined; + // The function pointer must not be comptime-known. + var t = S.f; + var frame_ptr = @asyncCall(&buffer, {}, t, .{ + F0, + .{ .f0 = 1, .f1 = 2 }, + F1, + [_]u8{ 1, 2, 3, 4, 5 }, + F2, + }); +}