From 71a733e3b5bda4e8baafac35c7140e0b3a0d9445 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 May 2019 13:04:15 +0100 Subject: [PATCH] Allow booleans to be assigned to a 1-bit bit field value --- src/check_stmt.cpp | 9 +++++++++ src/exact_value.cpp | 7 +++++++ src/ir.cpp | 17 ++++++++++------- src/ir_print.cpp | 4 ++-- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 9949e0bb7..82fc3bc7b 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -268,10 +268,19 @@ Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs) return rhs->type; } } + } else if (rhs->value.kind == ExactValue_Bool) { + bool b = rhs->value.value_bool; + if (lhs_bits == 1) { + return rhs->type; + } } } else if (is_type_integer(rhs->type)) { // TODO(bill): Any other checks? return rhs->type; + } else if (is_type_boolean(rhs->type)) { + if (lhs_bits == 1) { + return rhs->type; + } } gbString lhs_expr = expr_to_string(lhs->expr); gbString rhs_expr = expr_to_string(rhs->expr); diff --git a/src/exact_value.cpp b/src/exact_value.cpp index d1d44b7dd..428690291 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -280,6 +280,13 @@ ExactValue exact_value_from_basic_literal(Token token) { ExactValue exact_value_to_integer(ExactValue v) { switch (v.kind) { + case ExactValue_Bool: { + i64 i = 0; + if (v.value_bool) { + i = 1; + } + return exact_value_i64(i); + } case ExactValue_Integer: return v; case ExactValue_Float: { diff --git a/src/ir.cpp b/src/ir.cpp index 838415eaa..5eb1634d1 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -3377,6 +3377,7 @@ void ir_addr_store(irProcedure *proc, irAddr const &addr, irValue *value) { } irValue *ptr = ir_emit_conv(proc, bytes, alloc_type_pointer(int_type)); + irValue *sv = ir_emit_load(proc, ptr, 1); // NOTE(bill): Zero out the lower bits that need to be stored to sv = ir_emit_arith(proc, Token_Shr, sv, ir_const_int(size_in_bits), int_type); @@ -3393,23 +3394,25 @@ void ir_addr_store(irProcedure *proc, irAddr const &addr, irValue *value) { { irValue *shift_amount = ir_const_int(bit_inset); + irValue *ptr = ir_emit_conv(proc, bytes, alloc_type_pointer(t_u8)); + irValue *v = ir_emit_conv(proc, value, t_u8); - v = ir_emit_arith(proc, Token_Shl, v, shift_amount, int_type); + v = ir_emit_arith(proc, Token_Shl, v, shift_amount, t_u8); irValue *sv = ir_emit_load(proc, bytes, 1); // NOTE(bill): Zero out the upper bits that need to be stored to - sv = ir_emit_arith(proc, Token_Shl, sv, ir_const_int(bit_inset), int_type); - sv = ir_emit_arith(proc, Token_Shr, sv, ir_const_int(bit_inset), int_type); + sv = ir_emit_arith(proc, Token_Shl, sv, ir_const_int(8-bit_inset), t_u8); + sv = ir_emit_arith(proc, Token_Shr, sv, ir_const_int(8-bit_inset), t_u8); - v = ir_emit_arith(proc, Token_Or, sv, v, int_type); - ir_emit_store(proc, bytes, v, true); + v = ir_emit_arith(proc, Token_Or, sv, v, t_u8); + ir_emit_store(proc, ptr, v, true); } // Remaining bytes if (bit_inset+size_in_bits > 8) { - irValue *shift_amount = ir_const_int(bit_inset); irValue *ptr = ir_emit_conv(proc, ir_emit_ptr_offset(proc, bytes, v_one), alloc_type_pointer(int_type)); - irValue *v = ir_emit_arith(proc, Token_Shr, value, shift_amount, int_type); + irValue *v = ir_emit_conv(proc, value, int_type); + v = ir_emit_arith(proc, Token_Shr, v, ir_const_int(8-bit_inset), int_type); irValue *sv = ir_emit_load(proc, ptr, 1); // NOTE(bill): Zero out the lower bits that need to be stored to diff --git a/src/ir_print.cpp b/src/ir_print.cpp index fb3da8f69..46bcfc139 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -661,9 +661,9 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type * switch (value.kind) { case ExactValue_Bool: if (value.value_bool) { - ir_write_string(f, type == t_llvm_bool ? str_lit("true") : str_lit("1")); + ir_write_string(f, are_types_identical(type, t_llvm_bool) ? str_lit("true") : str_lit("1")); } else { - ir_write_string(f, type == t_llvm_bool ? str_lit("false") : str_lit("0")); + ir_write_string(f, are_types_identical(type, t_llvm_bool) ? str_lit("false") : str_lit("0")); } break; case ExactValue_String: {