authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-26 15:43:57-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-26 15:43:57-07:00
log79702c144d713de126d37637630c7b25ee9ecc82
tree71a39e1be451f8265ab12cdca56c67e924711208
parentc6b3d06535f4227541c13fe75da347a485abdb4f

Sema: fix ret_ptr when inlining

Previously, it would emit a ret_ptr AIR instruction but that is not correct because such an instruction would reference the result pointer of the caller function rather than the callee function. Instead, we emit an alloc instruction in this case. `ret_load` already handles inlining correctly.

2 files changed, 39 insertions(+), 0 deletions(-)

src/Sema.zig+8
......@@ -1958,6 +1958,14 @@ fn zirRetPtr(
19581958 .pointee_type = sema.fn_ret_ty,
19591959 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
19601960 });
1961
1962 if (block.inlining != null) {
1963 // We are inlining a function call; this should be emitted as an alloc, not a ret_ptr.
1964 // TODO when functions gain result location support, the inlining struct in
1965 // Block should contain the return pointer, and we would pass that through here.
1966 return block.addTy(.alloc, ptr_type);
1967 }
1968
19611969 return block.addTy(.ret_ptr, ptr_type);
19621970}
19631971
test/behavior/fn.zig+31
......@@ -90,3 +90,34 @@ test "discard the result of a function that returns a struct" {
9090 S.entry();
9191 comptime S.entry();
9292}
93
94test "inline function call that calls optional function pointer, return pointer at callsite interacts correctly with callsite return type" {
95 const S = struct {
96 field: u32,
97
98 fn doTheTest() !void {
99 bar2 = actualFn;
100 const result = try foo();
101 try expect(result.field == 1234);
102 }
103
104 const Foo = struct { field: u32 };
105
106 fn foo() !Foo {
107 var res: Foo = undefined;
108 res.field = bar();
109 return res;
110 }
111
112 inline fn bar() u32 {
113 return bar2.?();
114 }
115
116 var bar2: ?fn () u32 = null;
117
118 fn actualFn() u32 {
119 return 1234;
120 }
121 };
122 try S.doTheTest();
123}