Browse Source

Disallow slicing of constant values

gingerBill 4 years ago
parent
commit
b01c2e1017
2 changed files with 28 additions and 4 deletions
  1. 10 3
      src/check_expr.cpp
  2. 18 1
      src/llvm_backend.cpp

+ 10 - 3
src/check_expr.cpp

@@ -7811,10 +7811,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
 			return kind;
 			return kind;
 		}
 		}
 
 
-		o->mode = Addressing_Value;
-
 		if (se->low == nullptr && se->high != nullptr) {
 		if (se->low == nullptr && se->high != nullptr) {
-			// error(se->interval0, "1st index is required if a 2nd index is specified");
 			// It is okay to continue as it will assume the 1st index is zero
 			// It is okay to continue as it will assume the 1st index is zero
 		}
 		}
 
 
@@ -7849,6 +7846,16 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
 			}
 			}
 		}
 		}
 
 
+		if (max_count < 0)  {
+			if (o->mode == Addressing_Constant) {
+				gbString s = expr_to_string(se->expr);
+				error(se->expr, "Cannot slice constant value '%s'", s);
+				gb_string_free(s);
+			}
+		}
+
+		o->mode = Addressing_Value;
+
 		if (is_type_string(t) && max_count >= 0) {
 		if (is_type_string(t) && max_count >= 0) {
 			bool all_constant = true;
 			bool all_constant = true;
 			for (isize i = 0; i < gb_count_of(nodes); i++) {
 			for (isize i = 0; i < gb_count_of(nodes); i++) {

+ 18 - 1
src/llvm_backend.cpp

@@ -11360,6 +11360,15 @@ lbValue lb_find_ident(lbProcedure *p, lbModule *m, Entity *e, Ast *expr) {
 	return {};
 	return {};
 }
 }
 
 
+bool lb_is_expr_constant_zero(Ast *expr) {
+	GB_ASSERT(expr != nullptr);
+	auto v = exact_value_to_integer(expr->tav.value);
+	if (v.kind == ExactValue_Integer) {
+		return big_int_cmp_zero(&v.value_integer) == 0;
+	}
+	return false;
+}
+
 lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
 lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 
 
@@ -11683,6 +11692,13 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
 	case_end;
 	case_end;
 
 
 	case_ast_node(se, SliceExpr, expr);
 	case_ast_node(se, SliceExpr, expr);
+		if (is_type_slice(type_of_expr(se->expr))) {
+			// NOTE(bill): Quick optimization
+			if (se->high == nullptr &&
+			    (se->low == nullptr || lb_is_expr_constant_zero(se->low))) {
+				return lb_build_expr(p, se->expr);
+			}
+		}
 		return lb_addr_load(p, lb_build_addr(p, expr));
 		return lb_addr_load(p, lb_build_addr(p, expr));
 	case_end;
 	case_end;
 
 
@@ -12303,6 +12319,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
 	case_end;
 	case_end;
 
 
 	case_ast_node(se, SliceExpr, expr);
 	case_ast_node(se, SliceExpr, expr);
+
 		lbValue low  = lb_const_int(p->module, t_int, 0);
 		lbValue low  = lb_const_int(p->module, t_int, 0);
 		lbValue high = {};
 		lbValue high = {};
 
 
@@ -13268,7 +13285,7 @@ lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value) {
 	g.type = alloc_type_pointer(type);
 	g.type = alloc_type_pointer(type);
 	g.value = LLVMAddGlobal(m->mod, lb_type(m, type), cast(char const *)str);
 	g.value = LLVMAddGlobal(m->mod, lb_type(m, type), cast(char const *)str);
 	if (value.value != nullptr) {
 	if (value.value != nullptr) {
-		GB_ASSERT(LLVMIsConstant(value.value));
+		GB_ASSERT_MSG(LLVMIsConstant(value.value), LLVMPrintValueToString(value.value));
 		LLVMSetInitializer(g.value, value.value);
 		LLVMSetInitializer(g.value, value.value);
 	} else {
 	} else {
 		LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, type)));
 		LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, type)));