AstGen: fix ref instruction injection for functions

For the expressions regarding return type, alignment,
parameter type, etc.
This commit is contained in:
Andrew Kelley 2022-07-27 14:44:37 -07:00
parent 401abd793d
commit 6a4df2778e
2 changed files with 35 additions and 20 deletions

View File

@ -10282,11 +10282,11 @@ const GenZir = struct {
try astgen.extra.ensureUnusedCapacity( try astgen.extra.ensureUnusedCapacity(
gpa, gpa,
@typeInfo(Zir.Inst.FuncFancy).Struct.fields.len + @typeInfo(Zir.Inst.FuncFancy).Struct.fields.len +
fancyFnExprExtraLen(align_body, args.align_ref) + fancyFnExprExtraLen(astgen, align_body, args.align_ref) +
fancyFnExprExtraLen(addrspace_body, args.addrspace_ref) + fancyFnExprExtraLen(astgen, addrspace_body, args.addrspace_ref) +
fancyFnExprExtraLen(section_body, args.section_ref) + fancyFnExprExtraLen(astgen, section_body, args.section_ref) +
fancyFnExprExtraLen(cc_body, args.cc_ref) + fancyFnExprExtraLen(astgen, cc_body, args.cc_ref) +
fancyFnExprExtraLen(ret_body, ret_ref) + fancyFnExprExtraLen(astgen, ret_body, ret_ref) +
body_len + src_locs.len + body_len + src_locs.len +
@boolToInt(args.lib_name != 0) + @boolToInt(args.lib_name != 0) +
@boolToInt(args.noalias_bits != 0), @boolToInt(args.noalias_bits != 0),
@ -10322,36 +10322,36 @@ const GenZir = struct {
const zir_datas = astgen.instructions.items(.data); const zir_datas = astgen.instructions.items(.data);
if (align_body.len != 0) { if (align_body.len != 0) {
astgen.extra.appendAssumeCapacity(@intCast(u32, align_body.len)); astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, align_body));
astgen.extra.appendSliceAssumeCapacity(align_body); astgen.appendBodyWithFixups(align_body);
zir_datas[align_body[align_body.len - 1]].@"break".block_inst = new_index; zir_datas[align_body[align_body.len - 1]].@"break".block_inst = new_index;
} else if (args.align_ref != .none) { } else if (args.align_ref != .none) {
astgen.extra.appendAssumeCapacity(@enumToInt(args.align_ref)); astgen.extra.appendAssumeCapacity(@enumToInt(args.align_ref));
} }
if (addrspace_body.len != 0) { if (addrspace_body.len != 0) {
astgen.extra.appendAssumeCapacity(@intCast(u32, addrspace_body.len)); astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, addrspace_body));
astgen.extra.appendSliceAssumeCapacity(addrspace_body); astgen.appendBodyWithFixups(addrspace_body);
zir_datas[addrspace_body[addrspace_body.len - 1]].@"break".block_inst = new_index; zir_datas[addrspace_body[addrspace_body.len - 1]].@"break".block_inst = new_index;
} else if (args.addrspace_ref != .none) { } else if (args.addrspace_ref != .none) {
astgen.extra.appendAssumeCapacity(@enumToInt(args.addrspace_ref)); astgen.extra.appendAssumeCapacity(@enumToInt(args.addrspace_ref));
} }
if (section_body.len != 0) { if (section_body.len != 0) {
astgen.extra.appendAssumeCapacity(@intCast(u32, section_body.len)); astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, section_body));
astgen.extra.appendSliceAssumeCapacity(section_body); astgen.appendBodyWithFixups(section_body);
zir_datas[section_body[section_body.len - 1]].@"break".block_inst = new_index; zir_datas[section_body[section_body.len - 1]].@"break".block_inst = new_index;
} else if (args.section_ref != .none) { } else if (args.section_ref != .none) {
astgen.extra.appendAssumeCapacity(@enumToInt(args.section_ref)); astgen.extra.appendAssumeCapacity(@enumToInt(args.section_ref));
} }
if (cc_body.len != 0) { if (cc_body.len != 0) {
astgen.extra.appendAssumeCapacity(@intCast(u32, cc_body.len)); astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, cc_body));
astgen.extra.appendSliceAssumeCapacity(cc_body); astgen.appendBodyWithFixups(cc_body);
zir_datas[cc_body[cc_body.len - 1]].@"break".block_inst = new_index; zir_datas[cc_body[cc_body.len - 1]].@"break".block_inst = new_index;
} else if (args.cc_ref != .none) { } else if (args.cc_ref != .none) {
astgen.extra.appendAssumeCapacity(@enumToInt(args.cc_ref)); astgen.extra.appendAssumeCapacity(@enumToInt(args.cc_ref));
} }
if (ret_body.len != 0) { if (ret_body.len != 0) {
astgen.extra.appendAssumeCapacity(@intCast(u32, ret_body.len)); astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, ret_body));
astgen.extra.appendSliceAssumeCapacity(ret_body); astgen.appendBodyWithFixups(ret_body);
zir_datas[ret_body[ret_body.len - 1]].@"break".block_inst = new_index; zir_datas[ret_body[ret_body.len - 1]].@"break".block_inst = new_index;
} else if (ret_ref != .none) { } else if (ret_ref != .none) {
astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref)); astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref));
@ -10389,11 +10389,12 @@ const GenZir = struct {
try astgen.extra.ensureUnusedCapacity( try astgen.extra.ensureUnusedCapacity(
gpa, gpa,
@typeInfo(Zir.Inst.Func).Struct.fields.len + 1 + @typeInfo(Zir.Inst.Func).Struct.fields.len + 1 +
@maximum(ret_body.len, @boolToInt(ret_ref != .none)) + fancyFnExprExtraLen(astgen, ret_body, ret_ref) +
body_len + src_locs.len, body_len + src_locs.len,
); );
const ret_body_len = if (ret_body.len != 0) const ret_body_len = if (ret_body.len != 0)
@intCast(u32, ret_body.len) countBodyLenAfterFixups(astgen, ret_body)
else else
@boolToInt(ret_ref != .none); @boolToInt(ret_ref != .none);
@ -10404,7 +10405,7 @@ const GenZir = struct {
}); });
const zir_datas = astgen.instructions.items(.data); const zir_datas = astgen.instructions.items(.data);
if (ret_body.len != 0) { if (ret_body.len != 0) {
astgen.extra.appendSliceAssumeCapacity(ret_body); astgen.appendBodyWithFixups(ret_body);
zir_datas[ret_body[ret_body.len - 1]].@"break".block_inst = new_index; zir_datas[ret_body[ret_body.len - 1]].@"break".block_inst = new_index;
} else if (ret_ref != .none) { } else if (ret_ref != .none) {
astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref)); astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref));
@ -10435,10 +10436,10 @@ const GenZir = struct {
} }
} }
fn fancyFnExprExtraLen(body: []Zir.Inst.Index, ref: Zir.Inst.Ref) usize { fn fancyFnExprExtraLen(astgen: *AstGen, body: []Zir.Inst.Index, ref: Zir.Inst.Ref) u32 {
// In the case of non-empty body, there is one for the body length, // In the case of non-empty body, there is one for the body length,
// and then one for each instruction. // and then one for each instruction.
return body.len + @boolToInt(ref != .none); return countBodyLenAfterFixups(astgen, body) + @boolToInt(ref != .none);
} }
fn addVar(gz: *GenZir, args: struct { fn addVar(gz: *GenZir, args: struct {

View File

@ -408,3 +408,17 @@ test "function with inferred error set but returning no error" {
const return_ty = @typeInfo(@TypeOf(S.foo)).Fn.return_type.?; const return_ty = @typeInfo(@TypeOf(S.foo)).Fn.return_type.?;
try expectEqual(0, @typeInfo(@typeInfo(return_ty).ErrorUnion.error_set).ErrorSet.?.len); try expectEqual(0, @typeInfo(@typeInfo(return_ty).ErrorUnion.error_set).ErrorSet.?.len);
} }
test "import passed byref to function in return type" {
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
const S = struct {
fn get() @import("std").ArrayListUnmanaged(i32) {
var x: @import("std").ArrayListUnmanaged(i32) = .{};
return x;
}
};
var list = S.get();
try expect(list.items.len == 0);
}