diff --git a/src/Module.zig b/src/Module.zig index 4edba007e9..396e92ed79 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -5612,6 +5612,18 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air { else => |e| return e, }; + { + var it = sema.unresolved_inferred_allocs.keyIterator(); + while (it.next()) |ptr_inst| { + // The lack of a resolve_inferred_alloc means that this instruction + // is unused so it just has to be a no-op. + sema.air_instructions.set(ptr_inst.*, .{ + .tag = .alloc, + .data = .{ .ty = Type.initTag(.single_const_pointer_to_comptime_int) }, + }); + } + } + // If we don't get an error return trace from a caller, create our own. if (func.calls_or_awaits_errorable_fn and mod.comp.bin_file.options.error_return_tracing and diff --git a/src/Sema.zig b/src/Sema.zig index 06a4873a19..cb9d505e41 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -82,6 +82,8 @@ is_generic_instantiation: bool = false, /// function types will emit generic poison instead of a partial type. no_partial_func_ty: bool = false, +unresolved_inferred_allocs: std.AutoHashMapUnmanaged(Air.Inst.Index, void) = .{}, + const std = @import("std"); const math = std.math; const mem = std.mem; @@ -579,6 +581,7 @@ pub fn deinit(sema: *Sema) void { } sema.post_hoc_blocks.deinit(gpa); } + sema.unresolved_inferred_allocs.deinit(gpa); sema.* = undefined; } @@ -3238,6 +3241,7 @@ fn zirAllocExtended( ); try sema.requireFunctionBlock(block, src); try block.instructions.append(sema.gpa, Air.refToIndex(result).?); + try sema.unresolved_inferred_allocs.putNoClobber(sema.gpa, Air.refToIndex(result).?, {}); return result; } @@ -3414,6 +3418,7 @@ fn zirAllocInferred( ); try sema.requireFunctionBlock(block, src); try block.instructions.append(sema.gpa, Air.refToIndex(result).?); + try sema.unresolved_inferred_allocs.putNoClobber(sema.gpa, Air.refToIndex(result).?, {}); return result; } @@ -3463,6 +3468,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com } }, .inferred_alloc => { + assert(sema.unresolved_inferred_allocs.remove(ptr_inst)); const inferred_alloc = ptr_val.castTag(.inferred_alloc).?; const peer_inst_list = inferred_alloc.data.prongs.items(.stored_inst); const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_inst_list, .none); diff --git a/test/behavior.zig b/test/behavior.zig index a7b3ebfdda..0abf58290b 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -41,6 +41,7 @@ test { _ = @import("behavior/bugs/2006.zig"); _ = @import("behavior/bugs/2114.zig"); _ = @import("behavior/bugs/2346.zig"); + _ = @import("behavior/bugs/2557.zig"); _ = @import("behavior/bugs/2578.zig"); _ = @import("behavior/bugs/2692.zig"); _ = @import("behavior/bugs/2889.zig"); diff --git a/test/behavior/bugs/2557.zig b/test/behavior/bugs/2557.zig new file mode 100644 index 0000000000..05cf8156c0 --- /dev/null +++ b/test/behavior/bugs/2557.zig @@ -0,0 +1,6 @@ +test { + var a = if (true) { + return; + } else true; + _ = a; +}