| author | |
| committer | |
| log | 0f38410ea6f60ce9cebf373069d4abfcac0e77e6 |
| tree | a57673939888845bd3eb1553da5d6a23342e0e7f |
| parent | 59de23dfa010c5556f79fbb8b4c637c8d150fd88 |
| signature | Commit is signed but in an unrecognized format. |
7 files changed, 57 insertions(+), 3 deletions(-)
src-self-hosted/translate_c.zig+3| ... | ... | @@ -282,6 +282,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 282 | 282 | .PrivateExtern => return failDecl(c, fn_decl_loc, fn_name, "unsupported storage class: private extern", .{}), |
| 283 | 283 | .Auto => unreachable, // Not legal on functions |
| 284 | 284 | .Register => unreachable, // Not legal on functions |
| 285 | else => unreachable, | |
| 285 | 286 | }, |
| 286 | 287 | }; |
| 287 | 288 | const proto_node = switch (ZigClangType_getTypeClass(fn_type)) { |
| ... | ... | @@ -710,6 +711,7 @@ fn transBinaryOperator( |
| 710 | 711 | .XorAssign, |
| 711 | 712 | .OrAssign, |
| 712 | 713 | => unreachable, |
| 714 | else => unreachable, | |
| 713 | 715 | } |
| 714 | 716 | } |
| 715 | 717 | |
| ... | ... | @@ -1001,6 +1003,7 @@ fn transStringLiteral( |
| 1001 | 1003 | "TODO: support string literal kind {}", |
| 1002 | 1004 | .{kind}, |
| 1003 | 1005 | ), |
| 1006 | else => unreachable, | |
| 1004 | 1007 | } |
| 1005 | 1008 | } |
| 1006 | 1009 |
src/analyze.cpp+1-1| ... | ... | @@ -2682,7 +2682,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2682 | 2682 | |
| 2683 | 2683 | // Make sure the value is unique |
| 2684 | 2684 | auto entry = occupied_tag_values.put_unique(type_enum_field->value, field_node); |
| 2685 | if (entry != nullptr) { | |
| 2685 | if (entry != nullptr && enum_type->data.enumeration.layout != ContainerLayoutExtern) { | |
| 2686 | 2686 | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; |
| 2687 | 2687 | |
| 2688 | 2688 | Buf *val_buf = buf_alloc(); |
src/codegen.cpp+1-1| ... | ... | @@ -3292,7 +3292,7 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutable *executable, |
| 3292 | 3292 | LLVMValueRef tag_int_value = gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base), |
| 3293 | 3293 | instruction->target->value->type, tag_int_type, target_val); |
| 3294 | 3294 | |
| 3295 | if (ir_want_runtime_safety(g, &instruction->base)) { | |
| 3295 | if (ir_want_runtime_safety(g, &instruction->base) && wanted_type->data.enumeration.layout != ContainerLayoutExtern) { | |
| 3296 | 3296 | LLVMBasicBlockRef bad_value_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadValue"); |
| 3297 | 3297 | LLVMBasicBlockRef ok_value_block = LLVMAppendBasicBlock(g->cur_fn_val, "OkValue"); |
| 3298 | 3298 | size_t field_count = wanted_type->data.enumeration.src_field_count; |
src/ir.cpp+5-1| ... | ... | @@ -12728,7 +12728,7 @@ static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *sour |
| 12728 | 12728 | return ira->codegen->invalid_instruction; |
| 12729 | 12729 | |
| 12730 | 12730 | TypeEnumField *field = find_enum_field_by_tag(wanted_type, &val->data.x_bigint); |
| 12731 | if (field == nullptr) { | |
| 12731 | if (field == nullptr && wanted_type->data.enumeration.layout != ContainerLayoutExtern) { | |
| 12732 | 12732 | Buf *val_buf = buf_alloc(); |
| 12733 | 12733 | bigint_append_buf(val_buf, &val->data.x_bigint, 10); |
| 12734 | 12734 | ErrorMsg *msg = ir_add_error(ira, source_instr, |
| ... | ... | @@ -25791,6 +25791,10 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, |
| 25791 | 25791 | } |
| 25792 | 25792 | } |
| 25793 | 25793 | if (!instruction->have_else_prong) { |
| 25794 | if (switch_type->data.enumeration.layout == ContainerLayoutExtern) { | |
| 25795 | ir_add_error(ira, &instruction->base, | |
| 25796 | buf_sprintf("switch on an extern enum must have an else prong")); | |
| 25797 | } | |
| 25794 | 25798 | for (uint32_t i = 0; i < switch_type->data.enumeration.src_field_count; i += 1) { |
| 25795 | 25799 | TypeEnumField *enum_field = &switch_type->data.enumeration.fields[i]; |
| 25796 | 25800 |
test/compile_errors.zig+19| ... | ... | @@ -10,6 +10,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 10 | 10 | "tmp.zig:2:13: error: pointer type '[*]align(4) u8' requires aligned address", |
| 11 | 11 | }); |
| 12 | 12 | |
| 13 | cases.add("switch on extern enum missing else prong", | |
| 14 | \\const i = extern enum { | |
| 15 | \\ n = 0, | |
| 16 | \\ o = 2, | |
| 17 | \\ p = 4, | |
| 18 | \\ q = 4, | |
| 19 | \\}; | |
| 20 | \\pub fn main() void { | |
| 21 | \\ var x = @intToEnum(i, 52); | |
| 22 | \\ switch (x) { | |
| 23 | \\ .n, | |
| 24 | \\ .o, | |
| 25 | \\ .p => unreachable, | |
| 26 | \\ } | |
| 27 | \\} | |
| 28 | , &[_][]const u8{ | |
| 29 | "tmp.zig:9:5: error: switch on an extern enum must have an else prong", | |
| 30 | }); | |
| 31 | ||
| 13 | 32 | cases.add("invalid float literal", |
| 14 | 33 | \\const std = @import("std"); |
| 15 | 34 | \\ |
test/stage1/behavior/cast.zig+1| ... | ... | @@ -618,6 +618,7 @@ test "peer resolution of string literals" { |
| 618 | 618 | .b => "two", |
| 619 | 619 | .c => "three", |
| 620 | 620 | .d => "four", |
| 621 | else => unreachable, | |
| 621 | 622 | }; |
| 622 | 623 | expect(mem.eql(u8, cmd, "two")); |
| 623 | 624 | } |
test/stage1/behavior/enum.zig+27| ... | ... | @@ -1,6 +1,33 @@ |
| 1 | 1 | const expect = @import("std").testing.expect; |
| 2 | 2 | const mem = @import("std").mem; |
| 3 | 3 | |
| 4 | test "extern enum" { | |
| 5 | const S = struct { | |
| 6 | const i = extern enum { | |
| 7 | n = 0, | |
| 8 | o = 2, | |
| 9 | p = 4, | |
| 10 | q = 4, | |
| 11 | }; | |
| 12 | fn doTheTest(y: c_int) void { | |
| 13 | var x = i.o; | |
| 14 | expect(@enumToInt(x) == 2); | |
| 15 | x = @intToEnum(i, 12); | |
| 16 | expect(@enumToInt(x) == 12); | |
| 17 | x = @intToEnum(i, y); | |
| 18 | expect(@enumToInt(x) == 52); | |
| 19 | switch (x) { | |
| 20 | .n, | |
| 21 | .o, | |
| 22 | .p => unreachable, | |
| 23 | else => {}, | |
| 24 | } | |
| 25 | } | |
| 26 | }; | |
| 27 | S.doTheTest(52); | |
| 28 | comptime S.doTheTest(52); | |
| 29 | } | |
| 30 | ||
| 4 | 31 | test "enum type" { |
| 5 | 32 | const foo1 = Foo{ .One = 13 }; |
| 6 | 33 | const foo2 = Foo{ |