add C ABI test for big unions

This commit is contained in:
Andrew Kelley 2018-09-07 13:51:11 -04:00
parent 421ca1523f
commit 743b2e4afc
No known key found for this signature in database
GPG Key ID: 4E7CD66038A4D47C
3 changed files with 92 additions and 5 deletions

View File

@ -1838,6 +1838,7 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_ty
}
static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {
assert(var->di_loc_var != nullptr);
AstNode *source_node = var->decl_node;
ZigLLVMDILocation *debug_loc = ZigLLVMGetDebugLoc((unsigned)source_node->line + 1,
(unsigned)source_node->column + 1, get_di_scope(g, var->parent_scope));
@ -2119,11 +2120,12 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
di_arg_index = fn_walk->data.vars.gen_i;
var->value_ref = build_alloca(g, ty, buf_ptr(&var->name), var->align_bytes);
fn_walk->data.vars.gen_i += 1;
dest_ty = ty;
goto var_ok;
}
case FnWalkIdInits: {
clear_debug_source_node(g);
LLVMValueRef arg = LLVMGetParam(llvm_fn, fn_walk->data.inits.gen_i += 1);
LLVMValueRef arg = LLVMGetParam(llvm_fn, fn_walk->data.inits.gen_i);
LLVMTypeRef ptr_to_int_type_ref = LLVMPointerType(LLVMIntType((unsigned)ty_size * 8), 0);
LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, var->value_ref, ptr_to_int_type_ref, "");
gen_store_untyped(g, arg, bitcasted, var->align_bytes, false);

View File

@ -28,8 +28,6 @@ void zig_bool(bool);
void zig_array(uint8_t[10]);
static uint8_t array[10] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};
struct BigStruct {
uint64_t a;
uint64_t b;
@ -40,7 +38,19 @@ struct BigStruct {
void zig_big_struct(struct BigStruct);
static struct BigStruct s = {1, 2, 3, 4, 5};
union BigUnion {
struct BigStruct a;
};
void zig_big_union(union BigUnion);
struct SmallStructInts {
uint8_t a;
uint8_t b;
uint8_t c;
uint8_t d;
};
void zig_small_struct_ints(struct SmallStructInts);
void run_c_tests(void) {
zig_u8(0xff);
@ -60,9 +70,19 @@ void run_c_tests(void) {
zig_bool(true);
// TODO making this non-static crashes for some reason
static uint8_t array[10] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};
zig_array(array);
zig_big_struct(s);
{
struct BigStruct s = {1, 2, 3, 4, 5};
zig_big_struct(s);
}
{
struct SmallStructInts s = {1, 2, 3, 4};
zig_small_struct_ints(s);
}
}
void c_u8(uint8_t x) {
@ -133,3 +153,17 @@ void c_big_struct(struct BigStruct x) {
assert_or_panic(x.d == 4);
assert_or_panic(x.e == 5);
}
void c_big_union(union BigUnion x) {
assert_or_panic(x.a.a == 1);
assert_or_panic(x.a.b == 2);
assert_or_panic(x.a.c == 3);
assert_or_panic(x.a.d == 4);
}
void c_small_struct_ints(struct SmallStructInts x) {
assert_or_panic(x.a == 1);
assert_or_panic(x.b == 2);
assert_or_panic(x.c == 3);
assert_or_panic(x.d == 4);
}

View File

@ -130,3 +130,54 @@ export fn zig_big_struct(x: BigStruct) void {
assertOrPanic(x.d == 4);
assertOrPanic(x.e == 5);
}
const BigUnion = extern union {
a: BigStruct,
};
extern fn c_big_union(BigUnion) void;
test "C ABI big union" {
var x = BigUnion{
.a = BigStruct{
.a = 1,
.b = 2,
.c = 3,
.d = 4,
.e = 5,
},
};
c_big_union(x);
}
export fn zig_big_union(x: BigUnion) void {
assertOrPanic(x.a.a == 1);
assertOrPanic(x.a.b == 2);
assertOrPanic(x.a.c == 3);
assertOrPanic(x.a.d == 4);
assertOrPanic(x.a.e == 5);
}
const SmallStructInts = extern struct {
a: u8,
b: u8,
c: u8,
d: u8,
};
extern fn c_small_struct_ints(SmallStructInts) void;
test "C ABI small struct of ints" {
var s = SmallStructInts{
.a = 1,
.b = 2,
.c = 3,
.d = 4,
};
c_small_struct_ints(s);
}
export fn zig_small_struct_ints(x: SmallStructInts) void {
assertOrPanic(x.a == 1);
assertOrPanic(x.b == 2);
assertOrPanic(x.c == 3);
assertOrPanic(x.d == 4);
}