From 2e3dd8dd0b0af28d031f78791b738da514602f7b Mon Sep 17 00:00:00 2001 From: JasperGeer Date: Sun, 4 Sep 2022 15:31:05 -0400 Subject: Err on types passed as operands to ternary if expressions --- src/check_expr.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src/check_expr.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 54dc081cf..c3528c859 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -7347,6 +7347,13 @@ ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *node, Type *t check_expr_or_type(c, &x, te->x, type_hint); node->viral_state_flags |= te->x->viral_state_flags; + if (x.mode == Addressing_Type || x.mode == Addressing_Type) { + gbString type_string = expr_to_string(x.expr); + error(node, "Type %s is invalid operand for ternary if expression", type_string); + gb_string_free(type_string); + return kind; + } + if (te->y != nullptr) { Type *th = type_hint; if (type_hint == nullptr && is_type_typed(x.type)) { @@ -7359,6 +7366,13 @@ ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *node, Type *t return kind; } + if (y.mode == Addressing_Type || y.mode == Addressing_Type) { + gbString type_string = expr_to_string(y.expr); + error(node, "Type %s is invalid operand for ternary if expression", type_string); + gb_string_free(type_string); + return kind; + } + if (x.type == nullptr || x.type == t_invalid || y.type == nullptr || y.type == t_invalid) { return kind; -- cgit v1.2.3 From 23d93f68463bd0f486f468075a767525c5be1a59 Mon Sep 17 00:00:00 2001 From: JasperGeer Date: Sun, 4 Sep 2022 16:17:29 -0400 Subject: Remove unnecessary or --- src/check_expr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/check_expr.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index c3528c859..a9a0b2235 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -7347,7 +7347,7 @@ ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *node, Type *t check_expr_or_type(c, &x, te->x, type_hint); node->viral_state_flags |= te->x->viral_state_flags; - if (x.mode == Addressing_Type || x.mode == Addressing_Type) { + if (x.mode == Addressing_Type) { gbString type_string = expr_to_string(x.expr); error(node, "Type %s is invalid operand for ternary if expression", type_string); gb_string_free(type_string); @@ -7366,7 +7366,7 @@ ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *node, Type *t return kind; } - if (y.mode == Addressing_Type || y.mode == Addressing_Type) { + if (y.mode == Addressing_Type) { gbString type_string = expr_to_string(y.expr); error(node, "Type %s is invalid operand for ternary if expression", type_string); gb_string_free(type_string); -- cgit v1.2.3 From 17894add9569f08c279f5ec20ba40bf9365a9c9c Mon Sep 17 00:00:00 2001 From: JasperGeer Date: Sun, 4 Sep 2022 16:37:40 -0400 Subject: Remove redundant code --- src/check_expr.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'src/check_expr.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index a9a0b2235..0b6e108a3 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -7347,13 +7347,6 @@ ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *node, Type *t check_expr_or_type(c, &x, te->x, type_hint); node->viral_state_flags |= te->x->viral_state_flags; - if (x.mode == Addressing_Type) { - gbString type_string = expr_to_string(x.expr); - error(node, "Type %s is invalid operand for ternary if expression", type_string); - gb_string_free(type_string); - return kind; - } - if (te->y != nullptr) { Type *th = type_hint; if (type_hint == nullptr && is_type_typed(x.type)) { @@ -7366,8 +7359,9 @@ ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *node, Type *t return kind; } - if (y.mode == Addressing_Type) { - gbString type_string = expr_to_string(y.expr); + if (x.mode == Addressing_Type || y.mode == Addressing_Type) { + Ast *type_expr = (x.mode == Addressing_Type) ? x.expr : y.expr; + gbString type_string = expr_to_string(type_expr); error(node, "Type %s is invalid operand for ternary if expression", type_string); gb_string_free(type_string); return kind; -- cgit v1.2.3 From 37e23133e9877c6d30604be8d586363b3cf412ed Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 5 Sep 2022 16:06:40 +0100 Subject: Fix #2018 type assertion on untyped nil within a ternary if expression --- src/check_expr.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/check_expr.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 0b6e108a3..959bbb078 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -7359,13 +7359,13 @@ ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *node, Type *t return kind; } - if (x.mode == Addressing_Type || y.mode == Addressing_Type) { - Ast *type_expr = (x.mode == Addressing_Type) ? x.expr : y.expr; - gbString type_string = expr_to_string(type_expr); - error(node, "Type %s is invalid operand for ternary if expression", type_string); - gb_string_free(type_string); - return kind; - } + if (x.mode == Addressing_Type || y.mode == Addressing_Type) { + Ast *type_expr = (x.mode == Addressing_Type) ? x.expr : y.expr; + gbString type_string = expr_to_string(type_expr); + error(node, "Type %s is invalid operand for ternary if expression", type_string); + gb_string_free(type_string); + return kind; + } if (x.type == nullptr || x.type == t_invalid || y.type == nullptr || y.type == t_invalid) { @@ -7403,6 +7403,7 @@ ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *node, Type *t check_cast_internal(c, &y, type_hint)) { convert_to_typed(c, o, type_hint); update_untyped_expr_type(c, node, type_hint, !is_type_untyped(type_hint)); + o->type = type_hint; } } return kind; -- cgit v1.2.3 From 4998cf80c15555849d1ad119be3b2d4ff5cd6e1f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 5 Sep 2022 16:35:56 +0100 Subject: Fix #2017 mismatched types in binary matrix expression for `flt * (mat * vec)` --- src/check_expr.cpp | 5 ++++- src/llvm_backend_expr.cpp | 23 ++++++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) (limited to 'src/check_expr.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 959bbb078..f115dd6b2 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3039,8 +3039,8 @@ void check_binary_matrix(CheckerContext *c, Token const &op, Operand *x, Operand x->type = xt; goto matrix_success; } else { - GB_ASSERT(is_type_matrix(yt)); GB_ASSERT(!is_type_matrix(xt)); + GB_ASSERT(is_type_matrix(yt)); if (op.kind == Token_Mul) { // NOTE(bill): no need to handle the matrix case here since it should be handled above @@ -3061,6 +3061,9 @@ void check_binary_matrix(CheckerContext *c, Token const &op, Operand *x, Operand x->type = alloc_type_matrix(yt->Matrix.elem, 1, yt->Matrix.column_count); } goto matrix_success; + } else if (are_types_identical(yt->Matrix.elem, xt)) { + x->type = check_matrix_type_hint(y->type, type_hint); + return; } } if (!are_types_identical(xt, yt)) { diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 023e7b363..7c92c517c 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -1,4 +1,4 @@ -lbValue lb_emit_arith_matrix(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type, bool component_wise=false); +lbValue lb_emit_arith_matrix(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type, bool component_wise); lbValue lb_emit_logical_binary_expr(lbProcedure *p, TokenKind op, Ast *left, Ast *right, Type *type) { lbModule *m = p->module; @@ -987,7 +987,6 @@ lbValue lb_emit_vector_mul_matrix(lbProcedure *p, lbValue lhs, lbValue rhs, Type lbValue lb_emit_arith_matrix(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type, bool component_wise) { GB_ASSERT(is_type_matrix(lhs.type) || is_type_matrix(rhs.type)); - if (op == Token_Mul && !component_wise) { Type *xt = base_type(lhs.type); Type *yt = base_type(rhs.type); @@ -1001,8 +1000,22 @@ lbValue lb_emit_arith_matrix(lbProcedure *p, TokenKind op, lbValue lhs, lbValue } else if (is_type_array_like(xt)) { GB_ASSERT(yt->kind == Type_Matrix); return lb_emit_vector_mul_matrix(p, lhs, rhs, type); - } + } else { + GB_ASSERT(xt->kind == Type_Basic); + GB_ASSERT(yt->kind == Type_Matrix); + GB_ASSERT(is_type_matrix(type)); + + Type *array_type = alloc_type_array(yt->Matrix.elem, matrix_type_total_internal_elems(yt)); + GB_ASSERT(type_size_of(array_type) == type_size_of(yt)); + lbValue array_lhs = lb_emit_conv(p, lhs, array_type); + lbValue array_rhs = rhs; + array_rhs.type = array_type; + + lbValue array = lb_emit_arith(p, op, array_lhs, array_rhs, array_type); + array.type = type; + return array; + } } else { if (is_type_matrix(lhs.type)) { rhs = lb_emit_conv(p, rhs, lhs.type); @@ -1047,7 +1060,7 @@ lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Ty if (is_type_array_like(lhs.type) || is_type_array_like(rhs.type)) { return lb_emit_arith_array(p, op, lhs, rhs, type); } else if (is_type_matrix(lhs.type) || is_type_matrix(rhs.type)) { - return lb_emit_arith_matrix(p, op, lhs, rhs, type); + return lb_emit_arith_matrix(p, op, lhs, rhs, type, false); } else if (is_type_complex(type)) { lhs = lb_emit_conv(p, lhs, type); rhs = lb_emit_conv(p, rhs, type); @@ -1320,7 +1333,7 @@ lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) { if (is_type_matrix(be->left->tav.type) || is_type_matrix(be->right->tav.type)) { lbValue left = lb_build_expr(p, be->left); lbValue right = lb_build_expr(p, be->right); - return lb_emit_arith_matrix(p, be->op.kind, left, right, default_type(tv.type)); + return lb_emit_arith_matrix(p, be->op.kind, left, right, default_type(tv.type), false); } -- cgit v1.2.3 From b1dafcfe6dcdb73224a5cf7af7e8d9af48b1fbd7 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 5 Sep 2022 16:40:57 +0100 Subject: Fix #1992 `size_of` a relative slice crashes the compiler --- src/check_expr.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/check_expr.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index f115dd6b2..38d17c131 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -9586,6 +9586,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type case Ast_MapType: case Ast_BitSetType: case Ast_MatrixType: + case Ast_RelativeType: o->mode = Addressing_Type; o->type = check_type(c, node); break; -- cgit v1.2.3