From 25e74cb385dc353bcf0e56b35a6f1c7c8b13267e Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 4 Feb 2016 12:59:06 -0700 Subject: [PATCH] ability to explicitly cast bool to int --- src/all_types.hpp | 1 + src/analyze.cpp | 13 +++++++++++++ src/codegen.cpp | 5 +++++ test/self_hosted.zig | 15 +++++++++++++++ 4 files changed, 34 insertions(+) diff --git a/src/all_types.hpp b/src/all_types.hpp index c6baee6a4b8f7dd568b646e048be8f9cdd84ec69..70919f67e72149419aa6fb9c42363ca3057bba83 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -346,6 +346,7 @@ enum CastOp { CastOpErrToInt, CastOpIntToFloat, CastOpFloatToInt, + CastOpBoolToInt, }; struct AstNodeFnCallExpr { diff --git a/src/analyze.cpp b/src/analyze.cpp index 38bc656a1faf677f1b820843e11b868e32baa11c..7e63a43366331e4ddd4f8e84204c9cd9ee2dd25f 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3610,6 +3610,10 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex bignum_cast_to_int(&const_val->data.x_bignum, &other_val->data.x_bignum); const_val->ok = true; break; + case CastOpBoolToInt: + bignum_init_unsigned(&const_val->data.x_bignum, other_val->data.x_bool ? 1 : 0); + const_val->ok = true; + break; } } @@ -3643,6 +3647,15 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B return wanted_type; } + // explicit cast from bool to int + if (wanted_type->id == TypeTableEntryIdInt && + actual_type->id == TypeTableEntryIdBool) + { + node->data.fn_call_expr.cast_op = CastOpBoolToInt; + eval_const_expr_implicit_cast(g, node, expr_node); + return wanted_type; + } + // explicit cast from pointer to isize or usize if ((wanted_type == g->builtin_types.entry_isize || wanted_type == g->builtin_types.entry_usize) && actual_type->id == TypeTableEntryIdPointer) diff --git a/src/codegen.cpp b/src/codegen.cpp index 5c07b34097c65ba4f2326d6dfa2c9e46737ef946..e0a2784e95d48d5332bf152e435abd0f7cd13ba4 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -530,6 +530,11 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { return LLVMBuildFPToUI(g->builder, expr_val, wanted_type->type_ref, ""); } + case CastOpBoolToInt: + assert(wanted_type->id == TypeTableEntryIdInt); + assert(actual_type->id == TypeTableEntryIdBool); + return LLVMBuildZExt(g->builder, expr_val, wanted_type->type_ref, ""); + } zig_unreachable(); } diff --git a/test/self_hosted.zig b/test/self_hosted.zig index 82f4d553cf6b11d5d34c77b7508f7d0403ac1697..048b820ec95f01edf8f6e5033d6aec97c04963a9 100644 --- a/test/self_hosted.zig +++ b/test/self_hosted.zig @@ -82,3 +82,18 @@ fn continue_in_for_loop() { } if (sum != 6) unreachable{} } + + +#attribute("test") +fn cast_bool_to_int() { + const t = true; + const f = false; + if (i32(t) != i32(1)) unreachable{} + if (i32(f) != i32(0)) unreachable{} + non_const_cast_bool_to_int(t, f); +} + +fn non_const_cast_bool_to_int(t: bool, f: bool) { + if (i32(t) != i32(1)) unreachable{} + if (i32(f) != i32(0)) unreachable{} +} -- 2.54.0