Commit aa2586de18

Jimmi Holst Christensen <jimmiholstchristensen@gmail.com>
2018-05-04 04:27:04
Fixed extern enums having the wrong size (#970)
Fixed extern enums having the wrong size See #977
1 parent 7337029
Changed files (2)
src
test
cases
src/analyze.cpp
@@ -2325,8 +2325,14 @@ static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type) {
     HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {};
     occupied_tag_values.init(field_count);
 
-    TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
+    TypeTableEntry *tag_int_type;
+    if (enum_type->data.enumeration.layout == ContainerLayoutExtern) {
+        tag_int_type = get_c_int_type(g, CIntTypeInt);
+    } else {
+        tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
+    }
 
+    // TODO: Are extern enums allowed to have an init_arg_expr?
     if (decl_node->data.container_decl.init_arg_expr != nullptr) {
         TypeTableEntry *wanted_tag_int_type = analyze_type_expr(g, scope, decl_node->data.container_decl.init_arg_expr);
         if (type_is_invalid(wanted_tag_int_type)) {
test/cases/enum.zig
@@ -392,3 +392,12 @@ test "enum with 1 field but explicit tag type should still have the tag type" {
     const Enum = enum(u8) { B = 2 };
     comptime @import("std").debug.assert(@sizeOf(Enum) == @sizeOf(u8));
 }
+
+test "empty extern enum with members" {
+    const E = extern enum {
+        A,
+        B,
+        C,
+    };
+    assert(@sizeOf(E) == @sizeOf(c_int));
+}