Commit 0f21d3d4d1
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);
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;
+}
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);
+}