Browse Source

Fixed #2044 Uninitialised constant struct member values can cause crash

Foo :: struct {
    x: i32,
    data: sa.Small_Array(10, i32),
}

defaultFoo :: Foo{
    x = 1,
    // The 'data' value is not set!
}

fmt.println(defaultFoo.data) // caused the bug
gingerBill 2 years ago
parent
commit
99a1a10286
1 changed files with 7 additions and 1 deletions
  1. 7 1
      src/check_expr.cpp

+ 7 - 1
src/check_expr.cpp

@@ -4022,6 +4022,7 @@ ExactValue get_constant_field_single(CheckerContext *c, ExactValue value, i32 in
 
 
 		if (cl->elems[0]->kind == Ast_FieldValue) {
 		if (cl->elems[0]->kind == Ast_FieldValue) {
 			if (is_type_struct(node->tav.type)) {
 			if (is_type_struct(node->tav.type)) {
+				bool found = false;
 				for_array(i, cl->elems) {
 				for_array(i, cl->elems) {
 					Ast *elem = cl->elems[i];
 					Ast *elem = cl->elems[i];
 					if (elem->kind != Ast_FieldValue) {
 					if (elem->kind != Ast_FieldValue) {
@@ -4033,9 +4034,14 @@ ExactValue get_constant_field_single(CheckerContext *c, ExactValue value, i32 in
 					defer (array_free(&sub_sel.index));
 					defer (array_free(&sub_sel.index));
 					if (sub_sel.index[0] == index) {
 					if (sub_sel.index[0] == index) {
 						value = fv->value->tav.value;
 						value = fv->value->tav.value;
+						found = true;
 						break;
 						break;
 					}
 					}
 				}
 				}
+				if (!found) {
+					// Use the zero value if it is not found
+					value = {};
+				}
 			} else if (is_type_array(node->tav.type) || is_type_enumerated_array(node->tav.type)) {
 			} else if (is_type_array(node->tav.type) || is_type_enumerated_array(node->tav.type)) {
 				for_array(i, cl->elems) {
 				for_array(i, cl->elems) {
 					Ast *elem = cl->elems[i];
 					Ast *elem = cl->elems[i];
@@ -4677,7 +4683,7 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ
 
 
 	switch (entity->kind) {
 	switch (entity->kind) {
 	case Entity_Constant:
 	case Entity_Constant:
-		operand->value = entity->Constant.value;
+	operand->value = entity->Constant.value;
 		operand->mode = Addressing_Constant;
 		operand->mode = Addressing_Constant;
 		if (operand->value.kind == ExactValue_Procedure) {
 		if (operand->value.kind == ExactValue_Procedure) {
 			Entity *proc = strip_entity_wrapping(operand->value.value_procedure);
 			Entity *proc = strip_entity_wrapping(operand->value.value_procedure);