Cast integer literals to their specified type

master
LemonBoy 2020-01-08 10:19:04 +01:00
parent fd7e69a2c0
commit 5b34697b21
3 changed files with 45 additions and 4 deletions

View File

@ -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 {

View File

@ -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;

View File

@ -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;