Browse Source

Fix union array bug (Issue #112)

Ginger Bill 8 years ago
parent
commit
8c7cf0dbb0
4 changed files with 32 additions and 24 deletions
  1. 2 1
      src/check_expr.cpp
  2. 22 22
      src/ir.cpp
  3. 1 1
      src/ir_print.cpp
  4. 7 0
      src/types.cpp

+ 2 - 1
src/check_expr.cpp

@@ -7677,7 +7677,8 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
 			isize index = 0;
 			isize elem_count = cl->elems.count;
 
-			if (is_type_any(base_type(elem_type))) {
+			Type *bet = base_type(elem_type);
+			if (!elem_type_can_be_constant(bet)) {
 				is_constant = false;
 			}
 

+ 22 - 22
src/ir.cpp

@@ -5077,7 +5077,7 @@ irValue *ir_get_using_variable(irProcedure *proc, Entity *e) {
 }
 
 bool ir_is_elem_const(irModule *m, AstNode *elem, Type *elem_type) {
-	if (base_type(elem_type) == t_any) {
+	if (!elem_type_can_be_constant(elem_type)) {
 		return false;
 	}
 	if (elem->kind == AstNode_FieldValue) {
@@ -5592,6 +5592,27 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
 			}
 		} break;
 
+		case Type_Map: {
+			if (cl->elems.count == 0) {
+				break;
+			}
+			gbAllocator a = proc->module->allocator;
+			{
+				irValue **args = gb_alloc_array(a, irValue *, 2);
+				args[0] = ir_gen_map_header(proc, v, type);
+				args[1] = ir_const_int(a, 2*cl->elems.count);
+				ir_emit_global_call(proc, "__dynamic_map_reserve", args, 2);
+			}
+			for_array(field_index, cl->elems) {
+				AstNode *elem = cl->elems[field_index];
+				ast_node(fv, FieldValue, elem);
+
+				irValue *key   = ir_build_expr(proc, fv->field);
+				irValue *value = ir_build_expr(proc, fv->value);
+				ir_insert_dynamic_map_key_and_value(proc, v, type, key, value);
+			}
+		} break;
+
 		case Type_DynamicArray: {
 			if (cl->elems.count == 0) {
 				break;
@@ -5630,27 +5651,6 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
 			}
 		} break;
 
-		case Type_Map: {
-			if (cl->elems.count == 0) {
-				break;
-			}
-			gbAllocator a = proc->module->allocator;
-			{
-				irValue **args = gb_alloc_array(a, irValue *, 2);
-				args[0] = ir_gen_map_header(proc, v, type);
-				args[1] = ir_const_int(a, 2*cl->elems.count);
-				ir_emit_global_call(proc, "__dynamic_map_reserve", args, 2);
-			}
-			for_array(field_index, cl->elems) {
-				AstNode *elem = cl->elems[field_index];
-				ast_node(fv, FieldValue, elem);
-
-				irValue *key   = ir_build_expr(proc, fv->field);
-				irValue *value = ir_build_expr(proc, fv->value);
-				ir_insert_dynamic_map_key_and_value(proc, v, type, key, value);
-			}
-		} break;
-
 		case Type_Array: {
 			if (cl->elems.count > 0) {
 				ir_emit_store(proc, v, ir_add_module_constant(proc->module, type, exact_value_compound(expr)));

+ 1 - 1
src/ir_print.cpp

@@ -399,7 +399,7 @@ void ir_print_compound_element(irFileBuffer *f, irModule *m, ExactValue v, Type
 	ir_print_type(f, m, elem_type);
 	ir_write_byte(f, ' ');
 
-	if (v.kind == ExactValue_Invalid || base_type(elem_type) == t_any) {
+	if (v.kind == ExactValue_Invalid || !elem_type_can_be_constant(elem_type)) {
 		if (ir_type_has_default_values(elem_type)) {
 			ir_print_exact_value(f, m, v, elem_type);
 		} else {

+ 7 - 0
src/types.cpp

@@ -1037,6 +1037,13 @@ bool type_has_nil(Type *t) {
 	return false;
 }
 
+bool elem_type_can_be_constant(Type *t) {
+	if (is_type_any(t) || is_type_union(t)) {
+		return false;
+	}
+	return true;
+}
+
 
 bool is_type_comparable(Type *t) {
 	t = base_type(t);