Commit abe6c2d585

Andrew Kelley <superjoe30@gmail.com>
2018-01-29 16:57:09
allow packed containers in extern functions
1 parent f66ac9a
Changed files (3)
src/analyze.cpp
@@ -1242,16 +1242,16 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {
         case TypeTableEntryIdPointer:
             return type_allowed_in_extern(g, type_entry->data.pointer.child_type);
         case TypeTableEntryIdStruct:
-            return type_entry->data.structure.layout == ContainerLayoutExtern;
+            return type_entry->data.structure.layout == ContainerLayoutExtern || type_entry->data.structure.layout == ContainerLayoutPacked;
         case TypeTableEntryIdMaybe:
             {
                 TypeTableEntry *child_type = type_entry->data.maybe.child_type;
                 return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn;
             }
         case TypeTableEntryIdEnum:
-            return type_entry->data.enumeration.layout == ContainerLayoutExtern;
+            return type_entry->data.enumeration.layout == ContainerLayoutExtern || type_entry->data.enumeration.layout == ContainerLayoutPacked;
         case TypeTableEntryIdUnion:
-            return type_entry->data.unionation.layout == ContainerLayoutExtern;
+            return type_entry->data.unionation.layout == ContainerLayoutExtern || type_entry->data.unionation.layout == ContainerLayoutPacked;
     }
     zig_unreachable();
 }
test/cases/misc.zig
@@ -617,3 +617,19 @@ test "cold function" {
 fn thisIsAColdFn() void {
     @setCold(true);
 }
+
+
+const PackedStruct = packed struct { a: u8, b: u8, };
+const PackedUnion = packed union { a: u8, b: u32, };
+const PackedEnum = packed enum { A, B, };
+
+test "packed struct, enum, union parameters in extern function" {
+    testPackedStuff(
+        PackedStruct{.a = 1, .b = 2},
+        PackedUnion{.a = 1},
+        PackedEnum.A,
+    );
+}
+
+export fn testPackedStuff(a: &const PackedStruct, b: &const PackedUnion, c: PackedEnum) void {
+}
test/compile_errors.zig
@@ -5,12 +5,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
         \\export fn foo() boid {}
     , ".tmp_source.zig:1:17: error: use of undeclared identifier 'boid'");
 
-    cases.add("function with non-extern enum parameter",
+    cases.add("function with non-extern non-packed enum parameter",
         \\const Foo = enum { A, B, C };
         \\export fn entry(foo: Foo) void { }
     , ".tmp_source.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");
 
-    cases.add("function with non-extern struct parameter",
+    cases.add("function with non-extern non-packed struct parameter",
         \\const Foo = struct {
         \\    A: i32,
         \\    B: f32,
@@ -19,7 +19,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
         \\export fn entry(foo: Foo) void { }
     , ".tmp_source.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");
 
-    cases.add("function with non-extern union parameter",
+    cases.add("function with non-extern non-packed union parameter",
         \\const Foo = union {
         \\    A: i32,
         \\    B: f32,