diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 3fbeef1ce..87e887d13 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -2419,7 +2419,29 @@ fn transConstantExpr(rp: RestorePoint, scope: *Scope, expr: *const ZigClangExpr, var result: ZigClangExprEvalResult = undefined; if (!ZigClangExpr_EvaluateAsConstantExpr(expr, &result, .EvaluateForCodeGen, rp.c.clang_context)) return revertAndWarn(rp, error.UnsupportedTranslation, ZigClangExpr_getBeginLoc(expr), "invalid constant expression", .{}); - return maybeSuppressResult(rp, scope, used, try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&result.Val))); + + var val_node: ?*ast.Node = null; + switch (ZigClangAPValue_getKind(&result.Val)) { + .Int => { + // See comment in `transIntegerLiteral` for why this code is here. + // @as(T, x) + const expr_base = @ptrCast(*const ZigClangExpr, expr); + const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as"); + const ty_node = try transQualType(rp, ZigClangExpr_getType(expr_base), ZigClangExpr_getBeginLoc(expr_base)); + try as_node.params.push(ty_node); + _ = try appendToken(rp.c, .Comma, ","); + + const int_lit_node = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&result.Val)); + try as_node.params.push(int_lit_node); + + as_node.rparen_token = try appendToken(rp.c, .RParen, ")"); + + return maybeSuppressResult(rp, scope, used, &as_node.base); + }, + else => { + return revertAndWarn(rp, error.UnsupportedTranslation, ZigClangExpr_getBeginLoc(expr), "unsupported constant expression kind", .{}); + }, + } } fn transPredefinedExpr(rp: RestorePoint, scope: *Scope, expr: *const ZigClangPredefinedExpr, used: ResultUsed) TransError!*ast.Node { diff --git a/test/run_translated_c.zig b/test/run_translated_c.zig index 23e8b671b..ae029dd5a 100644 --- a/test/run_translated_c.zig +++ b/test/run_translated_c.zig @@ -20,6 +20,25 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { \\} , ""); + cases.add("switch case", + \\#include + \\int lottery(unsigned int x) { + \\ switch (x) { + \\ case 3: return 0; + \\ case -1: return 3; + \\ case 8 ... 10: return x; + \\ default: return -1; + \\ } + \\} + \\int main(int argc, char **argv) { + \\ if (lottery(2) != -1) abort(); + \\ if (lottery(3) != 0) abort(); + \\ if (lottery(-1) != 3) abort(); + \\ if (lottery(9) != 9) abort(); + \\ return 0; + \\} + , ""); + cases.add("boolean values and expressions", \\#include \\static const _Bool false_val = 0; diff --git a/test/translate_c.zig b/test/translate_c.zig index 9451b8edb..2ad4a1564 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -1468,10 +1468,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ __case_1: { \\ __case_0: { \\ switch (i) { - \\ 0 => break :__case_0, - \\ 1...3 => break :__case_1, + \\ @as(c_int, 0) => break :__case_0, + \\ @as(c_int, 1)...@as(c_int, 3) => break :__case_1, \\ else => break :__default, - \\ 4 => break :__case_2, + \\ @as(c_int, 4) => break :__case_2, \\ } \\ } \\ res = 1;