From 743b2e4afc72f436a73977f896b32e6041785795 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 7 Sep 2018 13:51:11 -0400 Subject: [PATCH] add C ABI test for big unions --- src/codegen.cpp | 4 ++- test/stage1/c_abi/cfuncs.c | 42 ++++++++++++++++++++++++++++--- test/stage1/c_abi/main.zig | 51 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 5 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index d4de593529..8acc7e9702 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -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); diff --git a/test/stage1/c_abi/cfuncs.c b/test/stage1/c_abi/cfuncs.c index bfdaa006ef..393c3a4f5a 100644 --- a/test/stage1/c_abi/cfuncs.c +++ b/test/stage1/c_abi/cfuncs.c @@ -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); +} diff --git a/test/stage1/c_abi/main.zig b/test/stage1/c_abi/main.zig index 5f5e0b0ca6..ef425ceb67 100644 --- a/test/stage1/c_abi/main.zig +++ b/test/stage1/c_abi/main.zig @@ -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); +}