Commit 5b34697b21
Changed files (3)
src-self-hosted
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 {
test/run_translated_c.zig
@@ -20,6 +20,25 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
\\}
, "");
+ cases.add("switch case",
+ \\#include <stdlib.h>
+ \\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 <stdlib.h>
\\static const _Bool false_val = 0;
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;