diff options
| author | gingerBill <bill@gingerbill.org> | 2021-05-15 16:40:40 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-05-15 16:40:40 +0100 |
| commit | b01c2e101712cf58e60bfc41d85fc33b60fcf349 (patch) | |
| tree | 4eac823f639370f2a1dd229a3eb9e7ea5b72ba65 | |
| parent | 63b54ce7c695fb1e204fe77db029cdebf7206b28 (diff) | |
Disallow slicing of constant values
| -rw-r--r-- | src/check_expr.cpp | 13 | ||||
| -rw-r--r-- | src/llvm_backend.cpp | 19 |
2 files changed, 28 insertions, 4 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 51dad8f79..18f210b63 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -7811,10 +7811,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type return kind; } - o->mode = Addressing_Value; - 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 } @@ -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) { bool all_constant = true; for (isize i = 0; i < gb_count_of(nodes); i++) { diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index dc36100a4..66c45793b 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -11360,6 +11360,15 @@ lbValue lb_find_ident(lbProcedure *p, lbModule *m, Entity *e, Ast *expr) { 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) { lbModule *m = p->module; @@ -11683,6 +11692,13 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { case_end; 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)); case_end; @@ -12303,6 +12319,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { case_end; case_ast_node(se, SliceExpr, expr); + lbValue low = lb_const_int(p->module, t_int, 0); lbValue high = {}; @@ -13268,7 +13285,7 @@ lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value) { g.type = alloc_type_pointer(type); g.value = LLVMAddGlobal(m->mod, lb_type(m, type), cast(char const *)str); if (value.value != nullptr) { - GB_ASSERT(LLVMIsConstant(value.value)); + GB_ASSERT_MSG(LLVMIsConstant(value.value), LLVMPrintValueToString(value.value)); LLVMSetInitializer(g.value, value.value); } else { LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, type))); |