Commit 6624f9cd5c
2020-11-14 15:30:06
1 parent
7d0c461Changed files (2)
src
stage1
test
stage1
behavior
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;
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,
+ });
+}