From 82f1d592fae021fcfc737e3cb6c107b325fcf1ee Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 25 Apr 2021 19:42:59 +0200 Subject: [PATCH] stage1: Use correct alignment for asyncCall frame --- src/stage1/analyze.cpp | 2 +- src/stage1/analyze.hpp | 1 + src/stage1/ir.cpp | 8 ++++++-- test/compile_errors.zig | 4 +++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/stage1/analyze.cpp b/src/stage1/analyze.cpp index e1e0c496f6..f76ea85ca9 100644 --- a/src/stage1/analyze.cpp +++ b/src/stage1/analyze.cpp @@ -4769,7 +4769,7 @@ Error type_is_nonnull_ptr2(CodeGen *g, ZigType *type, bool *result) { return ErrorNone; } -static uint32_t get_async_frame_align_bytes(CodeGen *g) { +uint32_t get_async_frame_align_bytes(CodeGen *g) { // Due to how the frame structure is built the minimum alignment is the one // of a usize (or pointer). // label (grep this): [fn_frame_struct_layout] diff --git a/src/stage1/analyze.hpp b/src/stage1/analyze.hpp index cea48b893c..2815274f63 100644 --- a/src/stage1/analyze.hpp +++ b/src/stage1/analyze.hpp @@ -47,6 +47,7 @@ ZigType *get_test_fn_type(CodeGen *g); ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type); bool handle_is_ptr(CodeGen *g, ZigType *type_entry); Error emit_error_unless_callconv_allowed_for_target(CodeGen *g, AstNode *source_node, CallingConvention cc); +uint32_t get_async_frame_align_bytes(CodeGen *g); bool type_has_bits(CodeGen *g, ZigType *type_entry); Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result); diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index 176d50dc72..7edfe37c92 100644 --- a/src/stage1/ir.cpp +++ b/src/stage1/ir.cpp @@ -20659,8 +20659,12 @@ static IrInstGen *analyze_casted_new_stack(IrAnalyze *ira, IrInst* source_instr, get_fn_frame_type(ira->codegen, fn_entry), false); return ir_implicit_cast(ira, new_stack, needed_frame_type); } else { + // XXX The stack alignment is hardcoded to 16 here and in + // std.Target.stack_align. + const uint32_t required_align = is_async_call_builtin ? + get_async_frame_align_bytes(ira->codegen) : 16; ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, - false, false, PtrLenUnknown, target_fn_align(ira->codegen->zig_target), 0, 0, false); + false, false, PtrLenUnknown, required_align, 0, 0, false); ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); ira->codegen->need_frame_size_prefix_data = true; return ir_implicit_cast2(ira, new_stack_src, new_stack, u8_slice); @@ -30095,7 +30099,7 @@ static IrInstGen *ir_align_cast(IrAnalyze *ira, IrInstGen *target, uint32_t alig fn_type_id.alignment = align_bytes; result_type = get_fn_type(ira->codegen, &fn_type_id); } else if (target_type->id == ZigTypeIdAnyFrame) { - if (align_bytes >= target_fn_align(ira->codegen->zig_target)) { + if (align_bytes >= get_async_frame_align_bytes(ira->codegen)) { result_type = target_type; } else { ir_add_error(ira, &target->base, buf_sprintf("sub-aligned anyframe not allowed")); diff --git a/test/compile_errors.zig b/test/compile_errors.zig index bfa9b592b4..5b36027248 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2136,7 +2136,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\} \\fn func() callconv(.Async) void {} , &[_][]const u8{ - "tmp.zig:4:21: error: expected type '[]align(16) u8', found '*[64]u8'", + // Split the check in two as the alignment value is target dependent. + "tmp.zig:4:21: error: expected type '[]align(", + ") u8', found '*[64]u8'", }); cases.add("atomic orderings of fence Acquire or stricter",