diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 436ca0cc30..cf6d1ec3ef 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -5324,8 +5324,8 @@ pub const FuncGen = struct { }, }; - if (callee_ty.zigTypeTag(mod) == .Pointer) { - // Add argument attributes for function pointer calls. + { + // Add argument attributes. it = iterateParamTypes(o, fn_info); it.llvm_index += @intFromBool(sret); it.llvm_index += @intFromBool(err_return_tracing); diff --git a/test/c_abi/cfuncs.c b/test/c_abi/cfuncs.c index 545abdece7..262a3a794e 100644 --- a/test/c_abi/cfuncs.c +++ b/test/c_abi/cfuncs.c @@ -1034,3 +1034,20 @@ struct ByRef __attribute__((sysv_abi)) c_explict_sys_v(struct ByRef in) { return in; } #endif + + +struct byval_tail_callsite_attr_Point { + double x; + double y; +} Point; +struct byval_tail_callsite_attr_Size { + double width; + double height; +} Size; +struct byval_tail_callsite_attr_Rect { + struct byval_tail_callsite_attr_Point origin; + struct byval_tail_callsite_attr_Size size; +}; +double c_byval_tail_callsite_attr(struct byval_tail_callsite_attr_Rect in) { + return in.size.width; +} diff --git a/test/c_abi/main.zig b/test/c_abi/main.zig index c089173945..05f7f060ea 100644 --- a/test/c_abi/main.zig +++ b/test/c_abi/main.zig @@ -1216,3 +1216,58 @@ test "explicit Win64 calling convention" { const res = c_explict_sys_v(.{ .val = 1, .arr = undefined }); try expect(res.val == 42); } + +const byval_tail_callsite_attr = struct { + const struct_Point = extern struct { + x: f64, + y: f64, + }; + const struct_Size = extern struct { + width: f64, + height: f64, + }; + const struct_Rect = extern struct { + origin: struct_Point, + size: struct_Size, + }; + + const Point = extern struct { + x: f64, + y: f64, + }; + + const Size = extern struct { + width: f64, + height: f64, + }; + + const MyRect = extern struct { + origin: Point, + size: Size, + + fn run(self: MyRect) f64 { + return c_byval_tail_callsite_attr(cast(self)); + } + + fn cast(self: MyRect) struct_Rect { + return @bitCast(self); + } + + extern fn c_byval_tail_callsite_attr(struct_Rect) f64; + }; +}; + +test "byval tail callsite attribute" { + if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest; + if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; + + // Originally reported at https://github.com/ziglang/zig/issues/16290 + // the bug was that the extern function had the byval attribute, but + // zig did not put the byval attribute at the callsite. Some LLVM optimization + // passes would then pass undefined for that parameter. + var v: byval_tail_callsite_attr.MyRect = .{ + .origin = .{ .x = 1, .y = 2 }, + .size = .{ .width = 3, .height = 4 }, + }; + try expect(v.run() == 3.0); +}