Commit 9017efee22
Changed files (3)
src
src/codegen.cpp
@@ -354,8 +354,12 @@ static void addLLVMFnAttrInt(LLVMValueRef fn_val, const char *attr_name, uint64_
return addLLVMAttrInt(fn_val, -1, attr_name, attr_val);
}
-static void addLLVMArgAttr(LLVMValueRef arg_val, unsigned param_index, const char *attr_name) {
- return addLLVMAttr(arg_val, param_index + 1, attr_name);
+static void addLLVMArgAttr(LLVMValueRef fn_val, unsigned param_index, const char *attr_name) {
+ return addLLVMAttr(fn_val, param_index + 1, attr_name);
+}
+
+static void addLLVMArgAttrInt(LLVMValueRef fn_val, unsigned param_index, const char *attr_name, uint64_t attr_val) {
+ return addLLVMAttrInt(fn_val, param_index + 1, attr_name, attr_val);
}
static bool is_symbol_available(CodeGen *g, Buf *name) {
@@ -2096,6 +2100,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
switch (fn_walk->id) {
case FnWalkIdAttrs:
addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");
+ addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty));
fn_walk->data.attrs.gen_i += 1;
break;
case FnWalkIdCall:
@@ -2132,6 +2137,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
switch (fn_walk->id) {
case FnWalkIdAttrs:
addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "byval");
+ addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty));
addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");
fn_walk->data.attrs.gen_i += 1;
break;
@@ -2159,7 +2165,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
break;
}
return true;
- } else if (abi_class == X64CABIClass_INTEGER && ty_size <= 8) {
+ } else if (abi_class == X64CABIClass_INTEGER) {
switch (fn_walk->id) {
case FnWalkIdAttrs:
fn_walk->data.attrs.gen_i += 1;
test/stage1/c_abi/cfuncs.c
@@ -52,6 +52,13 @@ struct SmallStructInts {
};
void zig_small_struct_ints(struct SmallStructInts);
+struct SplitStructInts {
+ uint64_t a;
+ uint8_t b;
+ uint32_t c;
+};
+void zig_split_struct_ints(struct SplitStructInts);
+
void run_c_tests(void) {
zig_u8(0xff);
zig_u16(0xfffe);
@@ -83,6 +90,11 @@ void run_c_tests(void) {
struct SmallStructInts s = {1, 2, 3, 4};
zig_small_struct_ints(s);
}
+
+ {
+ struct SplitStructInts s = {1234, 100, 1337};
+ zig_split_struct_ints(s);
+ }
}
void c_u8(uint8_t x) {
@@ -167,3 +179,9 @@ void c_small_struct_ints(struct SmallStructInts x) {
assert_or_panic(x.c == 3);
assert_or_panic(x.d == 4);
}
+
+void c_split_struct_ints(struct SplitStructInts x) {
+ assert_or_panic(x.a == 1234);
+ assert_or_panic(x.b == 100);
+ assert_or_panic(x.c == 1337);
+}
test/stage1/c_abi/main.zig
@@ -181,3 +181,25 @@ export fn zig_small_struct_ints(x: SmallStructInts) void {
assertOrPanic(x.c == 3);
assertOrPanic(x.d == 4);
}
+
+const SplitStructInt = extern struct {
+ a: u64,
+ b: u8,
+ c: u32,
+};
+extern fn c_split_struct_ints(SplitStructInt) void;
+
+test "C ABI split struct of ints" {
+ var s = SplitStructInt{
+ .a = 1234,
+ .b = 100,
+ .c = 1337,
+ };
+ c_split_struct_ints(s);
+}
+
+export fn zig_split_struct_ints(x: SplitStructInt) void {
+ assertOrPanic(x.a == 1234);
+ assertOrPanic(x.b == 100);
+ assertOrPanic(x.c == 1337);
+}