Ver código fonte

Allow booleans to be assigned to a 1-bit bit field value

gingerBill 6 anos atrás
pai
commit
71a733e3b5
4 arquivos alterados com 28 adições e 9 exclusões
  1. 9 0
      src/check_stmt.cpp
  2. 7 0
      src/exact_value.cpp
  3. 10 7
      src/ir.cpp
  4. 2 2
      src/ir_print.cpp

+ 9 - 0
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);

+ 7 - 0
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: {

+ 10 - 7
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

+ 2 - 2
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: {