Commit 743b2e4afc

Andrew Kelley <superjoe30@gmail.com>
2018-09-07 19:51:11
add C ABI test for big unions
1 parent 421ca15
Changed files (3)
src
test
stage1
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);
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);
+}
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);
+}