From 17c8f108a4d4c753e087e23ff5722718a6cd7a6a Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 30 Jan 2020 17:50:50 -0500 Subject: drop @newStackCall this was causing unrelated behavior tests to fail. if this commit is reverted, the docs are good, but `@newStackCall` is already deprecated in favor of `@call`, supplying the `stack` property. --- src/ir.cpp | 33 --------------------------------- 1 file changed, 33 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index ef3426d111..4742d81b23 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -7145,39 +7145,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod IrInstSrc *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); } - case BuiltinFnIdNewStackCall: - { - if (node->data.fn_call_expr.params.length < 2) { - add_node_error(irb->codegen, node, - buf_sprintf("expected at least 2 arguments, found %" ZIG_PRI_usize, - node->data.fn_call_expr.params.length)); - return irb->codegen->invalid_inst_src; - } - - AstNode *new_stack_node = node->data.fn_call_expr.params.at(0); - IrInstSrc *new_stack = ir_gen_node(irb, new_stack_node, scope); - if (new_stack == irb->codegen->invalid_inst_src) - return new_stack; - - AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1); - IrInstSrc *fn_ref = ir_gen_node(irb, fn_ref_node, scope); - if (fn_ref == irb->codegen->invalid_inst_src) - return fn_ref; - - size_t arg_count = node->data.fn_call_expr.params.length - 2; - - IrInstSrc **args = allocate(arg_count); - for (size_t i = 0; i < arg_count; i += 1) { - AstNode *arg_node = node->data.fn_call_expr.params.at(i + 2); - args[i] = ir_gen_node(irb, arg_node, scope); - if (args[i] == irb->codegen->invalid_inst_src) - return args[i]; - } - - IrInstSrc *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, - nullptr, CallModifierNone, false, new_stack, result_loc); - return ir_lval_wrap(irb, scope, call, lval, result_loc); - } case BuiltinFnIdCall: { // Cast the options parameter to the options type ZigType *options_type = get_builtin_type(irb->codegen, "CallOptions"); -- cgit v1.2.3 From 94f7c560015f7cb7ed8046339e2d0724dc86fcd6 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Mar 2020 21:47:19 -0400 Subject: riscv: add -mrelax arg for C to work around upstream issue See #4485 --- src-self-hosted/stage2.zig | 27 ++++++++++++++++++ src/analyze.hpp | 8 +++++- src/codegen.cpp | 70 ++++++++++++++++++++++++++++------------------ src/ir.cpp | 2 +- src/stage2.h | 3 ++ 5 files changed, 81 insertions(+), 29 deletions(-) (limited to 'src/ir.cpp') diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig index f67200097c..ff6ef47344 100644 --- a/src-self-hosted/stage2.zig +++ b/src-self-hosted/stage2.zig @@ -912,6 +912,9 @@ const Stage2Target = extern struct { dynamic_linker: ?[*:0]const u8, standard_dynamic_linker_path: ?[*:0]const u8, + llvm_cpu_features_asm_ptr: [*]const [*:0]const u8, + llvm_cpu_features_asm_len: usize, + fn fromTarget(self: *Stage2Target, cross_target: CrossTarget) !void { const allocator = std.heap.c_allocator; @@ -943,6 +946,12 @@ const Stage2Target = extern struct { var llvm_features_buffer = try std.Buffer.initSize(allocator, 0); defer llvm_features_buffer.deinit(); + // Unfortunately we have to do the work twice, because Clang does not support + // the same command line parameters for CPU features when assembling code as it does + // when compiling C code. + var asm_features_list = std.ArrayList([*:0]const u8).init(allocator); + defer asm_features_list.deinit(); + for (target.cpu.arch.allFeaturesList()) |feature, index_usize| { const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize); const is_enabled = target.cpu.features.isEnabled(index); @@ -963,6 +972,21 @@ const Stage2Target = extern struct { } } + switch (target.cpu.arch) { + .riscv32, .riscv64 => { + if (std.Target.riscv.featureSetHas(target.cpu.features, .relax)) { + try asm_features_list.append("-mrelax"); + } else { + try asm_features_list.append("-mno-relax"); + } + }, + else => { + // TODO + // Argh, why doesn't the assembler accept the list of CPU features?! + // I don't see a way to do this other than hard coding everything. + }, + } + try cpu_builtin_str_buffer.append( \\ }), \\}; @@ -1128,6 +1152,7 @@ const Stage2Target = extern struct { null; const cache_hash_slice = cache_hash.toOwnedSlice(); + const asm_features = asm_features_list.toOwnedSlice(); self.* = .{ .arch = @enumToInt(target.cpu.arch) + 1, // skip over ZigLLVM_UnknownArch .vendor = 0, @@ -1135,6 +1160,8 @@ const Stage2Target = extern struct { .abi = @enumToInt(target.abi), .llvm_cpu_name = if (target.cpu.model.llvm_name) |s| s.ptr else null, .llvm_cpu_features = llvm_features_buffer.toOwnedSlice().ptr, + .llvm_cpu_features_asm_ptr = asm_features.ptr, + .llvm_cpu_features_asm_len = asm_features.len, .cpu_builtin_str = cpu_builtin_str_buffer.toOwnedSlice().ptr, .os_builtin_str = os_builtin_str_buffer.toOwnedSlice().ptr, .cache_hash = cache_hash_slice.ptr, diff --git a/src/analyze.hpp b/src/analyze.hpp index b6404b1882..a7828663b0 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -257,7 +257,13 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose LLVMTypeRef get_llvm_type(CodeGen *g, ZigType *type); ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type); -void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_path, bool translate_c); +enum CSourceKind { + CSourceKindAsm, + CSourceKindC, +}; + +void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_path, bool translate_c, + CSourceKind source_kind); void src_assert(bool ok, AstNode *source_node); bool is_container(ZigType *type_entry); diff --git a/src/codegen.cpp b/src/codegen.cpp index 7d4262d765..3edc99156f 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -9155,13 +9155,15 @@ static void detect_libc(CodeGen *g) { } // does not add the "cc" arg -void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_path, bool translate_c) { +void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_path, + bool translate_c, CSourceKind source_kind) +{ if (translate_c) { args.append("-x"); args.append("c"); } - if (out_dep_path != nullptr) { + if (source_kind != CSourceKindAsm && out_dep_path != nullptr) { args.append("-MD"); args.append("-MV"); args.append("-MF"); @@ -9176,10 +9178,12 @@ void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_pa } if (translate_c) { - // this gives us access to preprocessing entities, presumably at - // the cost of performance - args.append("-Xclang"); - args.append("-detailed-preprocessing-record"); + if (source_kind == CSourceKindC) { + // this gives us access to preprocessing entities, presumably at + // the cost of performance + args.append("-Xclang"); + args.append("-detailed-preprocessing-record"); + } } else { switch (g->err_color) { case ErrColorAuto: @@ -9212,26 +9216,29 @@ void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_pa args.append(include_dir); } - if (g->zig_target->is_native) { - if (target_supports_clang_march_native(g->zig_target)) { - args.append("-march=native"); - } - } else { - args.append("-target"); - args.append(buf_ptr(&g->llvm_triple_str)); + args.append("-target"); + args.append(buf_ptr(&g->llvm_triple_str)); - if (g->zig_target->llvm_cpu_name != nullptr) { - args.append("-Xclang"); - args.append("-target-cpu"); - args.append("-Xclang"); - args.append(g->zig_target->llvm_cpu_name); - } - if (g->zig_target->llvm_cpu_features != nullptr) { - args.append("-Xclang"); - args.append("-target-feature"); - args.append("-Xclang"); - args.append(g->zig_target->llvm_cpu_features); - } + switch (source_kind) { + case CSourceKindC: + if (g->zig_target->llvm_cpu_name != nullptr) { + args.append("-Xclang"); + args.append("-target-cpu"); + args.append("-Xclang"); + args.append(g->zig_target->llvm_cpu_name); + } + if (g->zig_target->llvm_cpu_features != nullptr) { + args.append("-Xclang"); + args.append("-target-feature"); + args.append("-Xclang"); + args.append(g->zig_target->llvm_cpu_features); + } + break; + case CSourceKindAsm: + break; + } + for (size_t i = 0; i < g->zig_target->llvm_cpu_features_asm_len; i += 1) { + args.append(g->zig_target->llvm_cpu_features_asm_ptr[i]); } if (g->zig_target->os == OsFreestanding) { @@ -9377,7 +9384,7 @@ void codegen_translate_c(CodeGen *g, Buf *full_path) { } ZigList clang_argv = {0}; - add_cc_args(g, clang_argv, out_dep_path_cstr, true); + add_cc_args(g, clang_argv, out_dep_path_cstr, true, CSourceKindC); clang_argv.append(buf_ptr(full_path)); @@ -9714,6 +9721,15 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) { Buf *c_source_basename = buf_alloc(); os_path_split(c_source_file, nullptr, c_source_basename); + CSourceKind c_source_kind; + if (buf_ends_with_str(c_source_basename, ".s") || + buf_ends_with_str(c_source_basename, ".S")) + { + c_source_kind = CSourceKindAsm; + } else { + c_source_kind = CSourceKindC; + } + Stage2ProgressNode *child_prog_node = stage2_progress_start(g->sub_progress_node, buf_ptr(c_source_basename), buf_len(c_source_basename), 0); @@ -9786,7 +9802,7 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) { } Buf *out_dep_path = buf_sprintf("%s.d", buf_ptr(out_obj_path)); - add_cc_args(g, args, buf_ptr(out_dep_path), false); + add_cc_args(g, args, buf_ptr(out_dep_path), false, c_source_kind); args.append("-o"); args.append(buf_ptr(out_obj_path)); diff --git a/src/ir.cpp b/src/ir.cpp index c8a60c3e57..913cd69cfe 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -25126,7 +25126,7 @@ static IrInstGen *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstSrcCImpo ZigList clang_argv = {0}; - add_cc_args(ira->codegen, clang_argv, buf_ptr(tmp_dep_file), true); + add_cc_args(ira->codegen, clang_argv, buf_ptr(tmp_dep_file), true, CSourceKindC); clang_argv.append(buf_ptr(&tmp_c_file_path)); diff --git a/src/stage2.h b/src/stage2.h index a66163eceb..8893b1e27b 100644 --- a/src/stage2.h +++ b/src/stage2.h @@ -293,6 +293,9 @@ struct ZigTarget { const char *os_builtin_str; const char *dynamic_linker; const char *standard_dynamic_linker_path; + + const char **llvm_cpu_features_asm_ptr; + size_t llvm_cpu_features_asm_len; }; // ABI warning -- cgit v1.2.3 From 5ec6a0ea028cd26e9042d4d7a944d5b085f921a4 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 25 Mar 2020 21:00:02 -0400 Subject: fix an invalid free having to do with bound functions this should fix the drone CI failure --- src/ir.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 46d936619f..da6a5cfcad 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -13028,6 +13028,9 @@ static IrInstGen *ir_const_fn(IrAnalyze *ira, IrInst *source_instr, ZigFn *fn_en static IrInstGen *ir_const_bound_fn(IrAnalyze *ira, IrInst *src_inst, ZigFn *fn_entry, IrInstGen *first_arg, IrInst *first_arg_src) { + // This is unfortunately required to avoid improperly freeing first_arg_src + ira_ref(ira); + IrInstGen *result = ir_const(ira, src_inst, get_bound_fn_type(ira->codegen, fn_entry)); result->value->data.x_bound_fn.fn = fn_entry; result->value->data.x_bound_fn.first_arg = first_arg; -- cgit v1.2.3 From ddd98a7f10767e2bea43fb35405a9414a02ecbdf Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 26 Mar 2020 12:34:16 -0400 Subject: prevent ptr cast from forcing alignment resolution unnecessarily --- src/ir.cpp | 44 +++++++++++++++++++++------------------ test/stage1/behavior/async_fn.zig | 16 ++++++++++++++ test/stage1/behavior/cast.zig | 4 ++-- 3 files changed, 42 insertions(+), 22 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index da6a5cfcad..a5b40cd5bc 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -237,7 +237,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val) static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, ZigValue *out_val, ZigValue *ptr_val); static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *ptr, - IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on); + IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on, + bool keep_bigger_alignment); static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstGen *value, UndefAllowed undef_allowed); static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align); static IrInstGen *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, @@ -15066,7 +15067,8 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr, dest_ptr_type = wanted_type->data.maybe.child_type; } if (dest_ptr_type != nullptr) { - return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true); + return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true, + false); } } @@ -15108,7 +15110,7 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr, actual_type->data.pointer.child_type, source_node, !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) { - return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true); + return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true, false); } // cast from integer to C pointer @@ -18576,7 +18578,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i result_loc->written = true; result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, - &parent_result_loc->base, ptr_type, &result_cast->base.source_instruction->base, false); + &parent_result_loc->base, ptr_type, &result_cast->base.source_instruction->base, false, false); return result_loc->resolved_loc; } case ResultLocIdBitCast: { @@ -18670,7 +18672,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i result_loc->written = true; result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, - &parent_result_loc->base, ptr_type, &result_bit_cast->base.source_instruction->base, false); + &parent_result_loc->base, ptr_type, &result_bit_cast->base.source_instruction->base, false, false); return result_loc->resolved_loc; } } @@ -22947,7 +22949,7 @@ static IrInstGen *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstSrcSwi ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, ref_type->data.pointer.allow_zero); return ir_analyze_ptr_cast(ira, &instruction->base.base, target_value_ptr, - &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false); + &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false, false); } else { ir_add_error(ira, &instruction->base.base, buf_sprintf("switch on type '%s' provides no expression parameter", buf_ptr(&target_type->name))); @@ -23030,7 +23032,7 @@ static IrInstGen *ir_analyze_instruction_switch_else_var(IrAnalyze *ira, ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, ref_type->data.pointer.allow_zero); return ir_analyze_ptr_cast(ira, &instruction->base.base, target_value_ptr, - &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false); + &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false, false); } return target_value_ptr; @@ -27814,7 +27816,8 @@ static IrInstGen *ir_align_cast(IrAnalyze *ira, IrInstGen *target, uint32_t alig } static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *ptr, - IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on) + IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on, + bool keep_bigger_alignment) { Error err; @@ -27853,14 +27856,16 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn ir_add_error(ira, source_instr, buf_sprintf("cast discards const qualifier")); return ira->codegen->invalid_inst_gen; } - uint32_t src_align_bytes; - if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes))) - return ira->codegen->invalid_inst_gen; - uint32_t dest_align_bytes; if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes))) return ira->codegen->invalid_inst_gen; + uint32_t src_align_bytes = 0; + if (keep_bigger_alignment || dest_align_bytes != 1) { + if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes))) + return ira->codegen->invalid_inst_gen; + } + if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) return ira->codegen->invalid_inst_gen; @@ -27935,16 +27940,15 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn } result->value->type = dest_type; - // Keep the bigger alignment, it can only help- - // unless the target is zero bits. - if (src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) { + // Keep the bigger alignment, it can only help- unless the target is zero bits. + if (keep_bigger_alignment && src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) { result = ir_align_cast(ira, result, src_align_bytes, false); } return result; } - if (dest_align_bytes > src_align_bytes) { + if (src_align_bytes != 0 && dest_align_bytes > src_align_bytes) { ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); add_error_note(ira->codegen, msg, ptr_src->source_node, buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&src_type->name), src_align_bytes)); @@ -27955,10 +27959,9 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn IrInstGen *casted_ptr = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); - // Keep the bigger alignment, it can only help- - // unless the target is zero bits. + // Keep the bigger alignment, it can only help- unless the target is zero bits. IrInstGen *result; - if (src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) { + if (keep_bigger_alignment && src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) { result = ir_align_cast(ira, casted_ptr, src_align_bytes, false); if (type_is_invalid(result->value->type)) return ira->codegen->invalid_inst_gen; @@ -27979,8 +27982,9 @@ static IrInstGen *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstSrcPtrCa if (type_is_invalid(src_type)) return ira->codegen->invalid_inst_gen; + bool keep_bigger_alignment = true; return ir_analyze_ptr_cast(ira, &instruction->base.base, ptr, &instruction->ptr->base, - dest_type, &dest_type_value->base, instruction->safety_check_on); + dest_type, &dest_type_value->base, instruction->safety_check_on, keep_bigger_alignment); } static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ZigValue *val, size_t len) { diff --git a/test/stage1/behavior/async_fn.zig b/test/stage1/behavior/async_fn.zig index 6b99187563..958e9ea55f 100644 --- a/test/stage1/behavior/async_fn.zig +++ b/test/stage1/behavior/async_fn.zig @@ -1547,3 +1547,19 @@ test "noasync on function calls" { expectEqual(@as(i32, 42), noasync S1.c().b); expectEqual(@as(i32, 42), (try noasync S1.d()).b); } + +test "avoid forcing frame alignment resolution implicit cast to *c_void" { + const S = struct { + var x: ?*c_void = null; + + fn foo() bool { + suspend { + x = @frame(); + } + return true; + } + }; + var frame = async S.foo(); + resume @ptrCast(anyframe->bool, @alignCast(@alignOf(@Frame(S.foo)), S.x)); + expect(noasync await frame); +} diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig index 91e947e97d..b7bcb92c44 100644 --- a/test/stage1/behavior/cast.zig +++ b/test/stage1/behavior/cast.zig @@ -462,10 +462,10 @@ fn foobar(func: PFN_void) void { test "implicit ptr to *c_void" { var a: u32 = 1; - var ptr: *c_void = &a; + var ptr: *align(@alignOf(u32)) c_void = &a; var b: *u32 = @ptrCast(*u32, ptr); expect(b.* == 1); - var ptr2: ?*c_void = &a; + var ptr2: ?*align(@alignOf(u32)) c_void = &a; var c: *u32 = @ptrCast(*u32, ptr2.?); expect(c.* == 1); } -- cgit v1.2.3 From 0d4354324c17a15689118d259c069a6ee094dab4 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 26 Mar 2020 12:54:59 -0400 Subject: fix behavior tests compile error on i386-linux --- src/ir.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index a5b40cd5bc..4d5cfccabe 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -27759,6 +27759,13 @@ static IrInstGen *ir_align_cast(IrAnalyze *ira, IrInstGen *target, uint32_t alig old_align_bytes = fn_type_id.alignment; 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)) { + result_type = target_type; + } else { + ir_add_error(ira, &target->base, buf_sprintf("sub-aligned anyframe not allowed")); + return ira->codegen->invalid_inst_gen; + } } else if (target_type->id == ZigTypeIdOptional && target_type->data.maybe.child_type->id == ZigTypeIdPointer) { -- cgit v1.2.3