Commit 904f774563

Veikka Tuominen <git@vexu.eu>
2021-03-03 10:58:09
translate-c: fix c tokenizer giving invalid tokens
1 parent 7fbe9e7
lib/std/c/tokenizer.zig
@@ -401,7 +401,9 @@ pub const Tokenizer = struct {
             Zero,
             IntegerLiteralOct,
             IntegerLiteralBinary,
+            IntegerLiteralBinaryFirst,
             IntegerLiteralHex,
+            IntegerLiteralHexFirst,
             IntegerLiteral,
             IntegerSuffix,
             IntegerSuffixU,
@@ -1046,10 +1048,10 @@ pub const Tokenizer = struct {
                         state = .IntegerLiteralOct;
                     },
                     'b', 'B' => {
-                        state = .IntegerLiteralBinary;
+                        state = .IntegerLiteralBinaryFirst;
                     },
                     'x', 'X' => {
-                        state = .IntegerLiteralHex;
+                        state = .IntegerLiteralHexFirst;
                     },
                     '.' => {
                         state = .FloatFraction;
@@ -1066,6 +1068,13 @@ pub const Tokenizer = struct {
                         self.index -= 1;
                     },
                 },
+                .IntegerLiteralBinaryFirst => switch (c) {
+                    '0'...'7' => state = .IntegerLiteralBinary,
+                    else => {
+                        result.id = .Invalid;
+                        break;
+                    },
+                },
                 .IntegerLiteralBinary => switch (c) {
                     '0', '1' => {},
                     else => {
@@ -1073,6 +1082,19 @@ pub const Tokenizer = struct {
                         self.index -= 1;
                     },
                 },
+                .IntegerLiteralHexFirst => switch (c) {
+                    '0'...'9', 'a'...'f', 'A'...'F' => state = .IntegerLiteralHex,
+                    '.' => {
+                        state = .FloatFractionHex;
+                    },
+                    'p', 'P' => {
+                        state = .FloatExponent;
+                    },
+                    else => {
+                        result.id = .Invalid;
+                        break;
+                    },
+                },
                 .IntegerLiteralHex => switch (c) {
                     '0'...'9', 'a'...'f', 'A'...'F' => {},
                     '.' => {
@@ -1238,6 +1260,8 @@ pub const Tokenizer = struct {
                 .MultiLineCommentAsterisk,
                 .FloatExponent,
                 .MacroString,
+                .IntegerLiteralBinaryFirst,
+                .IntegerLiteralHexFirst,
                 => result.id = .Invalid,
 
                 .FloatExponentDigits => result.id = if (counter == 0) .Invalid else .{ .FloatLiteral = .none },
@@ -1523,6 +1547,7 @@ test "num suffixes" {
         \\ 1.0f 1.0L 1.0 .0 1.
         \\ 0l 0lu 0ll 0llu 0
         \\ 1u 1ul 1ull 1
+        \\ 0x 0b
         \\
     , &[_]Token.Id{
         .{ .FloatLiteral = .f },
@@ -1542,6 +1567,9 @@ test "num suffixes" {
         .{ .IntegerLiteral = .llu },
         .{ .IntegerLiteral = .none },
         .Nl,
+        .Invalid,
+        .Invalid,
+        .Nl,
     });
 }
 
lib/std/multi_array_list.zig
@@ -136,7 +136,7 @@ pub fn MultiArrayList(comptime S: type) type {
             const slices = self.slice();
             var result: S = undefined;
             inline for (fields) |field_info, i| {
-                @field(elem, field_info.name) = slices.items(@intToEnum(Field, i))[index];
+                @field(result, field_info.name) = slices.items(@intToEnum(Field, i))[index];
             }
             return result;
         }
test/run_translated_c.zig
@@ -27,6 +27,8 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
         \\#define FOO =
         \\#define PtrToPtr64(p) ((void *POINTER_64) p)
         \\#define STRUC_ALIGNED_STACK_COPY(t,s) ((CONST t *)(s))
+        \\#define bar = 0x
+        \\#define baz = 0b
         \\int main(void) {}
     , "");