authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-04 11:06:28+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-04 11:06:28+01:00
log51e430fac01a4b36a61d4c626d7c25158898e216
treee3ab74a8aa91b9e33e81eeaace59a7436e0e123d
parent6ea193946da13a42ecd8f8d46e4a140f9937d1e5

Fix edge case in hex-literal translation


3 files changed, 37 insertions(+), 12 deletions(-)

src-self-hosted/c_tokenizer.zig+10
......@@ -659,6 +659,16 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
659659 try failDecl(ctx, loc, name, "macro tokenizing failed: invalid digit '{c}' in octal number", .{c});
660660 return error.TokenizingFailed;
661661 },
662 'u', 'U' => {
663 state = .NumLitIntSuffixU;
664 result.num_lit_suffix = .U;
665 result.bytes = chars[begin_index..i.*];
666 },
667 'l', 'L' => {
668 state = .NumLitIntSuffixL;
669 result.num_lit_suffix = .L;
670 result.bytes = chars[begin_index..i.*];
671 },
662672 else => {
663673 result.bytes = chars[begin_index..i.*];
664674 return result;
src-self-hosted/translate_c.zig+21-12
......@@ -2125,7 +2125,8 @@ fn transForLoop(
21252125 block_scope = try Scope.Block.init(rp.c, scope, null);
21262126 block_scope.?.block_node = try transCreateNodeBlock(rp.c, null);
21272127 loop_scope.parent = &block_scope.?.base;
2128 _ = try transStmt(rp, &loop_scope, init, .unused, .r_value);
2128 const init_stmt = try transStmt(rp, &loop_scope, init, .unused, .r_value);
2129 try block_scope.?.block_node.statements.push(init_stmt);
21292130 }
21302131 var cond_scope = Scope{
21312132 .parent = scope,
......@@ -4720,18 +4721,26 @@ fn parseCExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigClangSou
47204721
47214722fn parseCNumLit(c: *Context, tok: *CToken, source_loc: ZigClangSourceLocation) ParseError!*ast.Node {
47224723 if (tok.id == .NumLitInt) {
4723 if (tok.num_lit_suffix == .None) {
4724 if (tok.bytes.len > 2 and tok.bytes[0] == '0') {
4725 switch (tok.bytes[1]) {
4726 '0'...'7' => {
4727 // octal
4728 return transCreateNodeInt(c, try std.fmt.allocPrint(c.a(), "0o{}", .{tok.bytes}));
4729 },
4730 else => {},
4731 }
4724 var lit_bytes = tok.bytes;
4725
4726 if (tok.bytes.len > 2 and tok.bytes[0] == '0') {
4727 switch (tok.bytes[1]) {
4728 '0'...'7' => {
4729 // Octal
4730 lit_bytes = try std.fmt.allocPrint(c.a(), "0o{}", .{tok.bytes});
4731 },
4732 'X' => {
4733 // Hexadecimal with capital X, valid in C but not in Zig
4734 lit_bytes = try std.fmt.allocPrint(c.a(), "0x{}", .{tok.bytes[2..]});
4735 },
4736 else => {},
47324737 }
4733 return transCreateNodeInt(c, tok.bytes);
47344738 }
4739
4740 if (tok.num_lit_suffix == .None) {
4741 return transCreateNodeInt(c, lit_bytes);
4742 }
4743
47354744 const cast_node = try transCreateNodeBuiltinFnCall(c, "@as");
47364745 try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.num_lit_suffix) {
47374746 .U => "c_uint",
......@@ -4742,7 +4751,7 @@ fn parseCNumLit(c: *Context, tok: *CToken, source_loc: ZigClangSourceLocation) P
47424751 else => unreachable,
47434752 }));
47444753 _ = try appendToken(c, .Comma, ",");
4745 try cast_node.params.push(try transCreateNodeInt(c, tok.bytes));
4754 try cast_node.params.push(try transCreateNodeInt(c, lit_bytes));
47464755 cast_node.rparen_token = try appendToken(c, .RParen, ")");
47474756 return &cast_node.base;
47484757 } else if (tok.id == .NumLitFloat) {
test/translate_c.zig+6
......@@ -2,6 +2,12 @@ const tests = @import("tests.zig");
22const builtin = @import("builtin");
33
44pub fn addCases(cases: *tests.TranslateCContext) void {
5 cases.add("#define hex literal with capital X",
6 \\#define VAL 0XF00D
7 , &[_][]const u8{
8 \\pub const VAL = 0xF00D;
9 });
10
511 cases.add("union initializer",
612 \\union { int x; char c[4]; }
713 \\ ua = {1},