From 51e430fac01a4b36a61d4c626d7c25158898e216 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 4 Jan 2020 11:06:28 +0100 Subject: [PATCH 1/2] Fix edge case in hex-literal translation --- src-self-hosted/c_tokenizer.zig | 10 ++++++++++ src-self-hosted/translate_c.zig | 33 +++++++++++++++++++++------------ test/translate_c.zig | 6 ++++++ 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src-self-hosted/c_tokenizer.zig b/src-self-hosted/c_tokenizer.zig index f6dfcef356..7cff969c35 100644 --- a/src-self-hosted/c_tokenizer.zig +++ b/src-self-hosted/c_tokenizer.zig @@ -659,6 +659,16 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*: try failDecl(ctx, loc, name, "macro tokenizing failed: invalid digit '{c}' in octal number", .{c}); return error.TokenizingFailed; }, + 'u', 'U' => { + state = .NumLitIntSuffixU; + result.num_lit_suffix = .U; + result.bytes = chars[begin_index..i.*]; + }, + 'l', 'L' => { + state = .NumLitIntSuffixL; + result.num_lit_suffix = .L; + result.bytes = chars[begin_index..i.*]; + }, else => { result.bytes = chars[begin_index..i.*]; return result; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 0b8fabc6c2..7f98ff2686 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -2125,7 +2125,8 @@ fn transForLoop( block_scope = try Scope.Block.init(rp.c, scope, null); block_scope.?.block_node = try transCreateNodeBlock(rp.c, null); loop_scope.parent = &block_scope.?.base; - _ = try transStmt(rp, &loop_scope, init, .unused, .r_value); + const init_stmt = try transStmt(rp, &loop_scope, init, .unused, .r_value); + try block_scope.?.block_node.statements.push(init_stmt); } var cond_scope = Scope{ .parent = scope, @@ -4720,18 +4721,26 @@ fn parseCExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigClangSou fn parseCNumLit(c: *Context, tok: *CToken, source_loc: ZigClangSourceLocation) ParseError!*ast.Node { if (tok.id == .NumLitInt) { - if (tok.num_lit_suffix == .None) { - if (tok.bytes.len > 2 and tok.bytes[0] == '0') { - switch (tok.bytes[1]) { - '0'...'7' => { - // octal - return transCreateNodeInt(c, try std.fmt.allocPrint(c.a(), "0o{}", .{tok.bytes})); - }, - else => {}, - } + var lit_bytes = tok.bytes; + + if (tok.bytes.len > 2 and tok.bytes[0] == '0') { + switch (tok.bytes[1]) { + '0'...'7' => { + // Octal + lit_bytes = try std.fmt.allocPrint(c.a(), "0o{}", .{tok.bytes}); + }, + 'X' => { + // Hexadecimal with capital X, valid in C but not in Zig + lit_bytes = try std.fmt.allocPrint(c.a(), "0x{}", .{tok.bytes[2..]}); + }, + else => {}, } - return transCreateNodeInt(c, tok.bytes); } + + if (tok.num_lit_suffix == .None) { + return transCreateNodeInt(c, lit_bytes); + } + const cast_node = try transCreateNodeBuiltinFnCall(c, "@as"); try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.num_lit_suffix) { .U => "c_uint", @@ -4742,7 +4751,7 @@ fn parseCNumLit(c: *Context, tok: *CToken, source_loc: ZigClangSourceLocation) P else => unreachable, })); _ = try appendToken(c, .Comma, ","); - try cast_node.params.push(try transCreateNodeInt(c, tok.bytes)); + try cast_node.params.push(try transCreateNodeInt(c, lit_bytes)); cast_node.rparen_token = try appendToken(c, .RParen, ")"); return &cast_node.base; } else if (tok.id == .NumLitFloat) { diff --git a/test/translate_c.zig b/test/translate_c.zig index 0299da7b7e..98cf3df996 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -2,6 +2,12 @@ const tests = @import("tests.zig"); const builtin = @import("builtin"); pub fn addCases(cases: *tests.TranslateCContext) void { + cases.add("#define hex literal with capital X", + \\#define VAL 0XF00D + , &[_][]const u8{ + \\pub const VAL = 0xF00D; + }); + cases.add("union initializer", \\union { int x; char c[4]; } \\ ua = {1}, From a712ea333b9ddb140331c159d23d16ef6ed4ef14 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 4 Jan 2020 11:49:43 +0100 Subject: [PATCH 2/2] Fix translation of for loop init Closes #4067 --- src-self-hosted/translate_c.zig | 10 ++++++---- test/translate_c.zig | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 7f98ff2686..57e67d4dd5 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -2119,14 +2119,16 @@ fn transForLoop( .parent = scope, .id = .Loop, }; - var block = false; + var block_scope: ?*Scope.Block = null; if (ZigClangForStmt_getInit(stmt)) |init| { block_scope = try Scope.Block.init(rp.c, scope, null); - block_scope.?.block_node = try transCreateNodeBlock(rp.c, null); + const block = try transCreateNodeBlock(rp.c, null); + block_scope.?.block_node = block; loop_scope.parent = &block_scope.?.base; - const init_stmt = try transStmt(rp, &loop_scope, init, .unused, .r_value); - try block_scope.?.block_node.statements.push(init_stmt); + const result = try transStmt(rp, &block_scope.?.base, init, .unused, .r_value); + if (result != &block.base) + try block.statements.push(result); } var cond_scope = Scope{ .parent = scope, diff --git a/test/translate_c.zig b/test/translate_c.zig index 98cf3df996..42b72e7cb9 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -696,6 +696,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\} }); + cases.add("for loop with simple init expression", + \\void foo(void) { + \\ int i; + \\ for (i = 3; i; i--) { } + \\} + , &[_][]const u8{ + \\pub export fn foo() void { + \\ var i: c_int = undefined; + \\ { + \\ i = 3; + \\ while (i != 0) : (i -= 1) {} + \\ } + \\} + }); + cases.add("break statement", \\void foo(void) { \\ for (;;) {