| author | |
| committer | |
| log | 25e74cb385dc353bcf0e56b35a6f1c7c8b13267e |
| tree | 09c18cff4b8e63c040db933fe9d321c2e0b09eca |
| parent | 32642ac9cb00b59fef97c1888e0424b0eb4db784 |
4 files changed, 34 insertions(+), 0 deletions(-)
src/all_types.hpp+1| ... | @@ -346,6 +346,7 @@ enum CastOp { | ... | @@ -346,6 +346,7 @@ enum CastOp { |
| 346 | CastOpErrToInt, | 346 | CastOpErrToInt, |
| 347 | CastOpIntToFloat, | 347 | CastOpIntToFloat, |
| 348 | CastOpFloatToInt, | 348 | CastOpFloatToInt, |
| 349 | CastOpBoolToInt, | ||
| 349 | }; | 350 | }; |
| 350 | 351 | ||
| 351 | struct AstNodeFnCallExpr { | 352 | struct AstNodeFnCallExpr { |
src/analyze.cpp+13| ... | @@ -3610,6 +3610,10 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex | ... | @@ -3610,6 +3610,10 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex |
| 3610 | bignum_cast_to_int(&const_val->data.x_bignum, &other_val->data.x_bignum); | 3610 | bignum_cast_to_int(&const_val->data.x_bignum, &other_val->data.x_bignum); |
| 3611 | const_val->ok = true; | 3611 | const_val->ok = true; |
| 3612 | break; | 3612 | break; |
| 3613 | case CastOpBoolToInt: | ||
| 3614 | bignum_init_unsigned(&const_val->data.x_bignum, other_val->data.x_bool ? 1 : 0); | ||
| 3615 | const_val->ok = true; | ||
| 3616 | break; | ||
| 3613 | } | 3617 | } |
| 3614 | } | 3618 | } |
| 3615 | 3619 | ||
| ... | @@ -3643,6 +3647,15 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B | ... | @@ -3643,6 +3647,15 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B |
| 3643 | return wanted_type; | 3647 | return wanted_type; |
| 3644 | } | 3648 | } |
| 3645 | 3649 | ||
| 3650 | // explicit cast from bool to int | ||
| 3651 | if (wanted_type->id == TypeTableEntryIdInt && | ||
| 3652 | actual_type->id == TypeTableEntryIdBool) | ||
| 3653 | { | ||
| 3654 | node->data.fn_call_expr.cast_op = CastOpBoolToInt; | ||
| 3655 | eval_const_expr_implicit_cast(g, node, expr_node); | ||
| 3656 | return wanted_type; | ||
| 3657 | } | ||
| 3658 | |||
| 3646 | // explicit cast from pointer to isize or usize | 3659 | // explicit cast from pointer to isize or usize |
| 3647 | if ((wanted_type == g->builtin_types.entry_isize || wanted_type == g->builtin_types.entry_usize) && | 3660 | if ((wanted_type == g->builtin_types.entry_isize || wanted_type == g->builtin_types.entry_usize) && |
| 3648 | actual_type->id == TypeTableEntryIdPointer) | 3661 | actual_type->id == TypeTableEntryIdPointer) |
src/codegen.cpp+5| ... | @@ -530,6 +530,11 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { | ... | @@ -530,6 +530,11 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { |
| 530 | return LLVMBuildFPToUI(g->builder, expr_val, wanted_type->type_ref, ""); | 530 | return LLVMBuildFPToUI(g->builder, expr_val, wanted_type->type_ref, ""); |
| 531 | } | 531 | } |
| 532 | 532 | ||
| 533 | case CastOpBoolToInt: | ||
| 534 | assert(wanted_type->id == TypeTableEntryIdInt); | ||
| 535 | assert(actual_type->id == TypeTableEntryIdBool); | ||
| 536 | return LLVMBuildZExt(g->builder, expr_val, wanted_type->type_ref, ""); | ||
| 537 | |||
| 533 | } | 538 | } |
| 534 | zig_unreachable(); | 539 | zig_unreachable(); |
| 535 | } | 540 | } |
test/self_hosted.zig+15| ... | @@ -82,3 +82,18 @@ fn continue_in_for_loop() { | ... | @@ -82,3 +82,18 @@ fn continue_in_for_loop() { |
| 82 | } | 82 | } |
| 83 | if (sum != 6) unreachable{} | 83 | if (sum != 6) unreachable{} |
| 84 | } | 84 | } |
| 85 | |||
| 86 | |||
| 87 | #attribute("test") | ||
| 88 | fn cast_bool_to_int() { | ||
| 89 | const t = true; | ||
| 90 | const f = false; | ||
| 91 | if (i32(t) != i32(1)) unreachable{} | ||
| 92 | if (i32(f) != i32(0)) unreachable{} | ||
| 93 | non_const_cast_bool_to_int(t, f); | ||
| 94 | } | ||
| 95 | |||
| 96 | fn non_const_cast_bool_to_int(t: bool, f: bool) { | ||
| 97 | if (i32(t) != i32(1)) unreachable{} | ||
| 98 | if (i32(f) != i32(0)) unreachable{} | ||
| 99 | } |