Browse Source

Fix #659 Compiler error when indexing constant slices

gingerBill 5 years ago
parent
commit
8057af9e09
1 changed files with 30 additions and 3 deletions
  1. 30 3
      src/check_expr.cpp

+ 30 - 3
src/check_expr.cpp

@@ -3197,6 +3197,9 @@ bool check_index_value(CheckerContext *c, bool open_range, Ast *index_value, i64
 
 
 				return true;
 				return true;
 			}
 			}
+		} else {
+			if (value) *value = exact_value_to_i64(operand.value);
+			return true;
 		}
 		}
 	}
 	}
 
 
@@ -3298,8 +3301,9 @@ ExactValue get_constant_field_single(CheckerContext *c, ExactValue value, i32 in
 						i64 field_index = exact_value_to_i64(index_value);
 						i64 field_index = exact_value_to_i64(index_value);
 						if (index == field_index) {
 						if (index == field_index) {
 							TypeAndValue tav = fv->value->tav;
 							TypeAndValue tav = fv->value->tav;
-							value = tav.value;
-							break;
+							if (success_) *success_ = true;
+							if (finish_) *finish_ = false;
+							return tav.value;;
 						}
 						}
 					}
 					}
 
 
@@ -3312,6 +3316,12 @@ ExactValue get_constant_field_single(CheckerContext *c, ExactValue value, i32 in
 				if (finish_) *finish_ = true;
 				if (finish_) *finish_ = true;
 				return empty_exact_value;
 				return empty_exact_value;
 			}
 			}
+			if (cl->elems.count <= index) {
+				if (success_) *success_ = false;
+				if (finish_) *finish_ = false;
+				return value;
+			}
+
 			TypeAndValue tav = cl->elems[index]->tav;
 			TypeAndValue tav = cl->elems[index]->tav;
 			if (tav.mode == Addressing_Constant) {
 			if (tav.mode == Addressing_Constant) {
 				if (success_) *success_ = true;
 				if (success_) *success_ = true;
@@ -9377,6 +9387,8 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
 
 
 		if (is_const) {
 		if (is_const) {
 			if (is_type_array(t)) {
 			if (is_type_array(t)) {
+				// OKay
+			} else if (is_type_slice(t)) {
 				// Okay
 				// Okay
 			} else if (is_type_enumerated_array(t)) {
 			} else if (is_type_enumerated_array(t)) {
 				// Okay
 				// Okay
@@ -9424,6 +9436,10 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
 		bool ok = check_index_value(c, false, ie->index, max_count, &index, index_type_hint);
 		bool ok = check_index_value(c, false, ie->index, max_count, &index, index_type_hint);
 		if (is_const) {
 		if (is_const) {
 			if (index < 0) {
 			if (index < 0) {
+				if (max_count < 0) {
+
+				}
+
 				gbString str = expr_to_string(o->expr);
 				gbString str = expr_to_string(o->expr);
 				error(o->expr, "Cannot index a constant '%s'", str);
 				error(o->expr, "Cannot index a constant '%s'", str);
 				error_line("\tSuggestion: store the constant into a variable in order to index it with a variable index\n");
 				error_line("\tSuggestion: store the constant into a variable in order to index it with a variable index\n");
@@ -9434,7 +9450,18 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
 			} else if (ok) {
 			} else if (ok) {
 				ExactValue value = type_and_value_of_expr(ie->expr).value;
 				ExactValue value = type_and_value_of_expr(ie->expr).value;
 				o->mode = Addressing_Constant;
 				o->mode = Addressing_Constant;
-				o->value = get_constant_field_single(c, value, cast(i32)index, nullptr, nullptr);
+				bool success = false;
+				bool finish = false;
+				o->value = get_constant_field_single(c, value, cast(i32)index, &success, &finish);
+				if (!success) {
+					gbString str = expr_to_string(o->expr);
+					error(o->expr, "Cannot index a constant '%s' with index %lld", str, cast(long long)index);
+					error_line("\tSuggestion: store the constant into a variable in order to index it with a variable index\n");
+					gb_string_free(str);
+					o->mode = Addressing_Invalid;
+					o->expr = node;
+					return kind;
+				}
 			}
 			}
 		}
 		}
 	case_end;
 	case_end;