authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-08 10:19:04+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-08 10:19:04+01:00
log5b34697b21ec88f85d338144ef1f9afb6be2b25a
treeae977486b01bc5f1fd537be59a91ba92babe0d71
parentfd7e69a2c0895f08fe3b8a75fb142250678d5e1f

Cast integer literals to their specified type


3 files changed, 45 insertions(+), 4 deletions(-)

src-self-hosted/translate_c.zig+23-1
......@@ -2419,7 +2419,29 @@ fn transConstantExpr(rp: RestorePoint, scope: *Scope, expr: *const ZigClangExpr,
24192419 var result: ZigClangExprEvalResult = undefined;
24202420 if (!ZigClangExpr_EvaluateAsConstantExpr(expr, &result, .EvaluateForCodeGen, rp.c.clang_context))
24212421 return revertAndWarn(rp, error.UnsupportedTranslation, ZigClangExpr_getBeginLoc(expr), "invalid constant expression", .{});
2422 return maybeSuppressResult(rp, scope, used, try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&result.Val)));
2422
2423 var val_node: ?*ast.Node = null;
2424 switch (ZigClangAPValue_getKind(&result.Val)) {
2425 .Int => {
2426 // See comment in `transIntegerLiteral` for why this code is here.
2427 // @as(T, x)
2428 const expr_base = @ptrCast(*const ZigClangExpr, expr);
2429 const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");
2430 const ty_node = try transQualType(rp, ZigClangExpr_getType(expr_base), ZigClangExpr_getBeginLoc(expr_base));
2431 try as_node.params.push(ty_node);
2432 _ = try appendToken(rp.c, .Comma, ",");
2433
2434 const int_lit_node = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&result.Val));
2435 try as_node.params.push(int_lit_node);
2436
2437 as_node.rparen_token = try appendToken(rp.c, .RParen, ")");
2438
2439 return maybeSuppressResult(rp, scope, used, &as_node.base);
2440 },
2441 else => {
2442 return revertAndWarn(rp, error.UnsupportedTranslation, ZigClangExpr_getBeginLoc(expr), "unsupported constant expression kind", .{});
2443 },
2444 }
24232445}
24242446
24252447fn transPredefinedExpr(rp: RestorePoint, scope: *Scope, expr: *const ZigClangPredefinedExpr, used: ResultUsed) TransError!*ast.Node {
test/run_translated_c.zig+19
......@@ -20,6 +20,25 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
2020 \\}
2121 , "");
2222
23 cases.add("switch case",
24 \\#include <stdlib.h>
25 \\int lottery(unsigned int x) {
26 \\ switch (x) {
27 \\ case 3: return 0;
28 \\ case -1: return 3;
29 \\ case 8 ... 10: return x;
30 \\ default: return -1;
31 \\ }
32 \\}
33 \\int main(int argc, char **argv) {
34 \\ if (lottery(2) != -1) abort();
35 \\ if (lottery(3) != 0) abort();
36 \\ if (lottery(-1) != 3) abort();
37 \\ if (lottery(9) != 9) abort();
38 \\ return 0;
39 \\}
40 , "");
41
2342 cases.add("boolean values and expressions",
2443 \\#include <stdlib.h>
2544 \\static const _Bool false_val = 0;
test/translate_c.zig+3-3
......@@ -1468,10 +1468,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
14681468 \\ __case_1: {
14691469 \\ __case_0: {
14701470 \\ switch (i) {
1471 \\ 0 => break :__case_0,
1472 \\ 1...3 => break :__case_1,
1471 \\ @as(c_int, 0) => break :__case_0,
1472 \\ @as(c_int, 1)...@as(c_int, 3) => break :__case_1,
14731473 \\ else => break :__default,
1474 \\ 4 => break :__case_2,
1474 \\ @as(c_int, 4) => break :__case_2,
14751475 \\ }
14761476 \\ }
14771477 \\ res = 1;