| author | |
| committer | |
| log | b971c7d0ff1c0ef86ac8d6816eb5e115f0d648fa |
| tree | fab4cfd6e9141b25b9e75f48a2b9e5d7473a3b54 |
| parent | 6fd0dddf186f6435f422f2992f44ec9a35e09f20 |
| signature | Commit is signed but in an unrecognized format. |
5 files changed, 78 insertions(+), 42 deletions(-)
src-self-hosted/translate_c.zig+13-14| ... | @@ -440,7 +440,6 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { | ... | @@ -440,7 +440,6 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 440 | .PrivateExtern => return failDecl(c, fn_decl_loc, fn_name, "unsupported storage class: private extern", .{}), | 440 | .PrivateExtern => return failDecl(c, fn_decl_loc, fn_name, "unsupported storage class: private extern", .{}), |
| 441 | .Auto => unreachable, // Not legal on functions | 441 | .Auto => unreachable, // Not legal on functions |
| 442 | .Register => unreachable, // Not legal on functions | 442 | .Register => unreachable, // Not legal on functions |
| 443 | else => unreachable, | ||
| 444 | }, | 443 | }, |
| 445 | }; | 444 | }; |
| 446 | 445 | ||
| ... | @@ -953,6 +952,19 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No | ... | @@ -953,6 +952,19 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 953 | tld_node.semicolon_token = try appendToken(c, .Semicolon, ";"); | 952 | tld_node.semicolon_token = try appendToken(c, .Semicolon, ";"); |
| 954 | try addTopLevelDecl(c, field_name, &tld_node.base); | 953 | try addTopLevelDecl(c, field_name, &tld_node.base); |
| 955 | } | 954 | } |
| 955 | // make non exhaustive | ||
| 956 | const field_node = try c.a().create(ast.Node.ContainerField); | ||
| 957 | field_node.* = .{ | ||
| 958 | .doc_comments = null, | ||
| 959 | .comptime_token = null, | ||
| 960 | .name_token = try appendIdentifier(c, "_"), | ||
| 961 | .type_expr = null, | ||
| 962 | .value_expr = null, | ||
| 963 | .align_expr = null, | ||
| 964 | }; | ||
| 965 | |||
| 966 | try container_node.fields_and_decls.push(&field_node.base); | ||
| 967 | _ = try appendToken(c, .Comma, ","); | ||
| 956 | container_node.rbrace_token = try appendToken(c, .RBrace, "}"); | 968 | container_node.rbrace_token = try appendToken(c, .RBrace, "}"); |
| 957 | 969 | ||
| 958 | break :blk &container_node.base; | 970 | break :blk &container_node.base; |
| ... | @@ -1231,18 +1243,6 @@ fn transBinaryOperator( | ... | @@ -1231,18 +1243,6 @@ fn transBinaryOperator( |
| 1231 | op_id = .BitOr; | 1243 | op_id = .BitOr; |
| 1232 | op_token = try appendToken(rp.c, .Pipe, "|"); | 1244 | op_token = try appendToken(rp.c, .Pipe, "|"); |
| 1233 | }, | 1245 | }, |
| 1234 | .Assign, | ||
| 1235 | .MulAssign, | ||
| 1236 | .DivAssign, | ||
| 1237 | .RemAssign, | ||
| 1238 | .AddAssign, | ||
| 1239 | .SubAssign, | ||
| 1240 | .ShlAssign, | ||
| 1241 | .ShrAssign, | ||
| 1242 | .AndAssign, | ||
| 1243 | .XorAssign, | ||
| 1244 | .OrAssign, | ||
| 1245 | => unreachable, | ||
| 1246 | else => unreachable, | 1246 | else => unreachable, |
| 1247 | } | 1247 | } |
| 1248 | 1248 | ||
| ... | @@ -1678,7 +1678,6 @@ fn transStringLiteral( | ... | @@ -1678,7 +1678,6 @@ fn transStringLiteral( |
| 1678 | "TODO: support string literal kind {}", | 1678 | "TODO: support string literal kind {}", |
| 1679 | .{kind}, | 1679 | .{kind}, |
| 1680 | ), | 1680 | ), |
| 1681 | else => unreachable, | ||
| 1682 | } | 1681 | } |
| 1683 | } | 1682 | } |
| 1684 | 1683 |
test/compile_errors.zig+22-19| ... | @@ -2,6 +2,28 @@ const tests = @import("tests.zig"); | ... | @@ -2,6 +2,28 @@ const tests = @import("tests.zig"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | 3 | ||
| 4 | pub fn addCases(cases: *tests.CompileErrorContext) void { | 4 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5 | cases.addTest("non-exhaustive enums", | ||
| 6 | \\const E = enum { | ||
| 7 | \\ a, | ||
| 8 | \\ b, | ||
| 9 | \\ _, | ||
| 10 | \\}; | ||
| 11 | \\pub export fn entry() void { | ||
| 12 | \\ var e: E = .b; | ||
| 13 | \\ switch (e) { // error: switch not handling the tag `b` | ||
| 14 | \\ .a => {}, | ||
| 15 | \\ _ => {}, | ||
| 16 | \\ } | ||
| 17 | \\ switch (e) { // error: switch on non-exhaustive enum must include `else` or `_` prong | ||
| 18 | \\ .a => {}, | ||
| 19 | \\ .b => {}, | ||
| 20 | \\ } | ||
| 21 | \\} | ||
| 22 | , &[_][]const u8{ | ||
| 23 | "tmp.zig:8:5: error: enumeration value 'E.b' not handled in switch", | ||
| 24 | "tmp.zig:12:5: error: switch on non-exhaustive enum must include `else` or `_` prong", | ||
| 25 | }); | ||
| 26 | |||
| 5 | cases.addTest("@export with empty name string", | 27 | cases.addTest("@export with empty name string", |
| 6 | \\pub export fn entry() void { } | 28 | \\pub export fn entry() void { } |
| 7 | \\comptime { | 29 | \\comptime { |
| ... | @@ -139,25 +161,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -139,25 +161,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 139 | "tmp.zig:2:13: error: pointer type '[*]align(4) u8' requires aligned address", | 161 | "tmp.zig:2:13: error: pointer type '[*]align(4) u8' requires aligned address", |
| 140 | }); | 162 | }); |
| 141 | 163 | ||
| 142 | cases.add("switch on extern enum missing else prong", | ||
| 143 | \\const i = extern enum { | ||
| 144 | \\ n = 0, | ||
| 145 | \\ o = 2, | ||
| 146 | \\ p = 4, | ||
| 147 | \\ q = 4, | ||
| 148 | \\}; | ||
| 149 | \\pub fn main() void { | ||
| 150 | \\ var x = @intToEnum(i, 52); | ||
| 151 | \\ switch (x) { | ||
| 152 | \\ .n, | ||
| 153 | \\ .o, | ||
| 154 | \\ .p => unreachable, | ||
| 155 | \\ } | ||
| 156 | \\} | ||
| 157 | , &[_][]const u8{ | ||
| 158 | "tmp.zig:9:5: error: switch on an extern enum must have an else prong", | ||
| 159 | }); | ||
| 160 | |||
| 161 | cases.add("invalid float literal", | 164 | cases.add("invalid float literal", |
| 162 | \\const std = @import("std"); | 165 | \\const std = @import("std"); |
| 163 | \\ | 166 | \\ |
test/stage1/behavior/cast.zig-1| ... | @@ -618,7 +618,6 @@ test "peer resolution of string literals" { | ... | @@ -618,7 +618,6 @@ test "peer resolution of string literals" { |
| 618 | .b => "two", | 618 | .b => "two", |
| 619 | .c => "three", | 619 | .c => "three", |
| 620 | .d => "four", | 620 | .d => "four", |
| 621 | else => unreachable, | ||
| 622 | }; | 621 | }; |
| 623 | expect(mem.eql(u8, cmd, "two")); | 622 | expect(mem.eql(u8, cmd, "two")); |
| 624 | } | 623 | } |
test/stage1/behavior/enum.zig+32-8| ... | @@ -11,17 +11,41 @@ test "extern enum" { | ... | @@ -11,17 +11,41 @@ test "extern enum" { |
| 11 | }; | 11 | }; |
| 12 | fn doTheTest(y: c_int) void { | 12 | fn doTheTest(y: c_int) void { |
| 13 | var x = i.o; | 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) { | 14 | switch (x) { |
| 20 | .n, | 15 | .n, .p => unreachable, |
| 21 | .o, | 16 | .o => {}, |
| 22 | .p => unreachable, | 17 | } |
| 18 | } | ||
| 19 | }; | ||
| 20 | S.doTheTest(52); | ||
| 21 | comptime S.doTheTest(52); | ||
| 22 | } | ||
| 23 | |||
| 24 | test "non-exhaustive enum" { | ||
| 25 | const S = struct { | ||
| 26 | const E = enum(u8) { | ||
| 27 | a, | ||
| 28 | b, | ||
| 29 | _, | ||
| 30 | }; | ||
| 31 | fn doTheTest(y: u8) void { | ||
| 32 | var e: E = .b; | ||
| 33 | switch (e) { | ||
| 34 | .a => {}, | ||
| 35 | .b => {}, | ||
| 36 | _ => {}, | ||
| 37 | } | ||
| 38 | |||
| 39 | switch (e) { | ||
| 40 | .a => {}, | ||
| 41 | .b => {}, | ||
| 23 | else => {}, | 42 | else => {}, |
| 24 | } | 43 | } |
| 44 | expect(@enumToInt(e) == 1); | ||
| 45 | e = @intToEnum(E, 12); | ||
| 46 | expect(@enumToInt(e) == 12); | ||
| 47 | e = @intToEnum(E, y); | ||
| 48 | expect(@enumToInt(e) == 52); | ||
| 25 | } | 49 | } |
| 26 | }; | 50 | }; |
| 27 | S.doTheTest(52); | 51 | S.doTheTest(52); |
test/translate_c.zig+11| ... | @@ -629,6 +629,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -629,6 +629,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 629 | \\ VAL21 = 6917529027641081853, | 629 | \\ VAL21 = 6917529027641081853, |
| 630 | \\ VAL22 = 0, | 630 | \\ VAL22 = 0, |
| 631 | \\ VAL23 = -1, | 631 | \\ VAL23 = -1, |
| 632 | \\ _, | ||
| 632 | \\}; | 633 | \\}; |
| 633 | }); | 634 | }); |
| 634 | } | 635 | } |
| ... | @@ -990,6 +991,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -990,6 +991,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 990 | \\pub const FOO = @enumToInt(enum_enum_ty.FOO); | 991 | \\pub const FOO = @enumToInt(enum_enum_ty.FOO); |
| 991 | \\pub const enum_enum_ty = extern enum { | 992 | \\pub const enum_enum_ty = extern enum { |
| 992 | \\ FOO, | 993 | \\ FOO, |
| 994 | \\ _, | ||
| 993 | \\}; | 995 | \\}; |
| 994 | \\pub extern var my_enum: enum_enum_ty; | 996 | \\pub extern var my_enum: enum_enum_ty; |
| 995 | }); | 997 | }); |
| ... | @@ -1106,6 +1108,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1106,6 +1108,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1106 | \\ a, | 1108 | \\ a, |
| 1107 | \\ b, | 1109 | \\ b, |
| 1108 | \\ c, | 1110 | \\ c, |
| 1111 | \\ _, | ||
| 1109 | \\}; | 1112 | \\}; |
| 1110 | \\pub const d = enum_unnamed_1; | 1113 | \\pub const d = enum_unnamed_1; |
| 1111 | \\pub const e = @enumToInt(enum_unnamed_2.e); | 1114 | \\pub const e = @enumToInt(enum_unnamed_2.e); |
| ... | @@ -1115,6 +1118,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1115,6 +1118,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1115 | \\ e = 0, | 1118 | \\ e = 0, |
| 1116 | \\ f = 4, | 1119 | \\ f = 4, |
| 1117 | \\ g = 5, | 1120 | \\ g = 5, |
| 1121 | \\ _, | ||
| 1118 | \\}; | 1122 | \\}; |
| 1119 | \\pub export var h: enum_unnamed_2 = @intToEnum(enum_unnamed_2, e); | 1123 | \\pub export var h: enum_unnamed_2 = @intToEnum(enum_unnamed_2, e); |
| 1120 | \\pub const i = @enumToInt(enum_unnamed_3.i); | 1124 | \\pub const i = @enumToInt(enum_unnamed_3.i); |
| ... | @@ -1124,6 +1128,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1124,6 +1128,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1124 | \\ i, | 1128 | \\ i, |
| 1125 | \\ j, | 1129 | \\ j, |
| 1126 | \\ k, | 1130 | \\ k, |
| 1131 | \\ _, | ||
| 1127 | \\}; | 1132 | \\}; |
| 1128 | \\pub const struct_Baz = extern struct { | 1133 | \\pub const struct_Baz = extern struct { |
| 1129 | \\ l: enum_unnamed_3, | 1134 | \\ l: enum_unnamed_3, |
| ... | @@ -1136,6 +1141,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1136,6 +1141,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1136 | \\ n, | 1141 | \\ n, |
| 1137 | \\ o, | 1142 | \\ o, |
| 1138 | \\ p, | 1143 | \\ p, |
| 1144 | \\ _, | ||
| 1139 | \\}; | 1145 | \\}; |
| 1140 | , | 1146 | , |
| 1141 | \\pub const Baz = struct_Baz; | 1147 | \\pub const Baz = struct_Baz; |
| ... | @@ -1566,6 +1572,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1566,6 +1572,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1566 | \\const enum_unnamed_1 = extern enum { | 1572 | \\const enum_unnamed_1 = extern enum { |
| 1567 | \\ One, | 1573 | \\ One, |
| 1568 | \\ Two, | 1574 | \\ Two, |
| 1575 | \\ _, | ||
| 1569 | \\}; | 1576 | \\}; |
| 1570 | }); | 1577 | }); |
| 1571 | 1578 | ||
| ... | @@ -1669,6 +1676,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1669,6 +1676,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1669 | \\ A, | 1676 | \\ A, |
| 1670 | \\ B, | 1677 | \\ B, |
| 1671 | \\ C, | 1678 | \\ C, |
| 1679 | \\ _, | ||
| 1672 | \\}; | 1680 | \\}; |
| 1673 | \\pub const SomeTypedef = c_int; | 1681 | \\pub const SomeTypedef = c_int; |
| 1674 | \\pub export fn and_or_non_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void) c_int { | 1682 | \\pub export fn and_or_non_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void) c_int { |
| ... | @@ -1713,6 +1721,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1713,6 +1721,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1713 | \\pub const enum_Bar = extern enum { | 1721 | \\pub const enum_Bar = extern enum { |
| 1714 | \\ A, | 1722 | \\ A, |
| 1715 | \\ B, | 1723 | \\ B, |
| 1724 | \\ _, | ||
| 1716 | \\}; | 1725 | \\}; |
| 1717 | \\pub extern fn func(a: [*c]struct_Foo, b: [*c][*c]enum_Bar) void; | 1726 | \\pub extern fn func(a: [*c]struct_Foo, b: [*c][*c]enum_Bar) void; |
| 1718 | , | 1727 | , |
| ... | @@ -1977,6 +1986,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1977,6 +1986,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1977 | \\ A, | 1986 | \\ A, |
| 1978 | \\ B, | 1987 | \\ B, |
| 1979 | \\ C, | 1988 | \\ C, |
| 1989 | \\ _, | ||
| 1980 | \\}; | 1990 | \\}; |
| 1981 | \\pub export fn if_none_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void, arg_d: enum_SomeEnum) c_int { | 1991 | \\pub export fn if_none_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void, arg_d: enum_SomeEnum) c_int { |
| 1982 | \\ var a = arg_a; | 1992 | \\ var a = arg_a; |
| ... | @@ -2418,6 +2428,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -2418,6 +2428,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 2418 | \\ A = 2, | 2428 | \\ A = 2, |
| 2419 | \\ B = 5, | 2429 | \\ B = 5, |
| 2420 | \\ @"1" = 6, | 2430 | \\ @"1" = 6, |
| 2431 | \\ _, | ||
| 2421 | \\}; | 2432 | \\}; |
| 2422 | , | 2433 | , |
| 2423 | \\pub const Foo = enum_Foo; | 2434 | \\pub const Foo = enum_Foo; |