From 48de1a01a9bc5cdc2edda363681455078bae3e52 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 22 Oct 2021 13:14:19 +0100 Subject: Correct update propagation of type for ternary if expressions --- src/llvm_backend_expr.cpp | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'src/llvm_backend_expr.cpp') diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 763afacc2..caeae2fb0 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -762,6 +762,12 @@ lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) { case Token_Xor: case Token_AndNot: { Type *type = default_type(tv.type); + if (is_type_typed(be->left->tav.type) && is_type_untyped(be->right->tav.type)) { + be->right->tav.type = be->left->tav.type; + } else if (is_type_untyped(be->left->tav.type) && is_type_typed(be->right->tav.type)) { + be->left->tav.type = type_of_expr(be->right); + } + lbValue left = lb_build_expr(p, be->left); lbValue right = lb_build_expr(p, be->right); return lb_emit_arith(p, be->op.kind, left, right, type); @@ -2247,17 +2253,18 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { TokenPos expr_pos = ast_token(expr).pos; TypeAndValue tv = type_and_value_of_expr(expr); + Type *type = type_of_expr(expr); GB_ASSERT_MSG(tv.mode != Addressing_Invalid, "invalid expression '%s' (tv.mode = %d, tv.type = %s) @ %s\n Current Proc: %.*s : %s", expr_to_string(expr), tv.mode, type_to_string(tv.type), token_pos_to_string(expr_pos), LIT(p->name), type_to_string(p->type)); if (tv.value.kind != ExactValue_Invalid) { // NOTE(bill): The commented out code below is just for debug purposes only // GB_ASSERT_MSG(!is_type_untyped(tv.type), "%s @ %s\n%s", type_to_string(tv.type), token_pos_to_string(expr_pos), expr_to_string(expr)); - // if (is_type_untyped(tv.type)) { + // if (is_type_untyped(type)) { // gb_printf_err("%s %s\n", token_pos_to_string(expr_pos), expr_to_string(expr)); // } // NOTE(bill): Short on constant values - return lb_const_value(p->module, tv.type, tv.value); + return lb_const_value(p->module, type, tv.value); } #if 0 @@ -2288,12 +2295,12 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { case_ast_node(u, Undef, expr) lbValue res = {}; - if (is_type_untyped(tv.type)) { + if (is_type_untyped(type)) { res.value = nullptr; res.type = t_untyped_undef; } else { - res.value = LLVMGetUndef(lb_type(m, tv.type)); - res.type = tv.type; + res.value = LLVMGetUndef(lb_type(m, type)); + res.type = type; } return res; case_end; @@ -2334,7 +2341,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { TypeAndValue tav = type_and_value_of_expr(expr); GB_ASSERT(tav.mode == Addressing_Constant); - return lb_const_value(p->module, tv.type, tv.value); + return lb_const_value(p->module, type, tv.value); case_end; case_ast_node(se, SelectorCallExpr, expr); @@ -2407,7 +2414,6 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { case_ast_node(ta, TypeAssertion, expr); TokenPos pos = ast_token(expr).pos; - Type *type = tv.type; lbValue e = lb_build_expr(p, ta->expr); Type *t = type_deref(e.type); if (is_type_union(t)) { @@ -2427,16 +2433,16 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { lbValue e = lb_build_expr(p, tc->expr); switch (tc->token.kind) { case Token_cast: - return lb_emit_conv(p, e, tv.type); + return lb_emit_conv(p, e, type); case Token_transmute: - return lb_emit_transmute(p, e, tv.type); + return lb_emit_transmute(p, e, type); } GB_PANIC("Invalid AST TypeCast"); case_end; case_ast_node(ac, AutoCast, expr); lbValue value = lb_build_expr(p, ac->expr); - return lb_emit_conv(p, value, tv.type); + return lb_emit_conv(p, value, type); case_end; case_ast_node(ue, UnaryExpr, expr); @@ -2446,7 +2452,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { default: { lbValue v = lb_build_expr(p, ue->expr); - return lb_emit_unary_arith(p, ue->op.kind, v, tv.type); + return lb_emit_unary_arith(p, ue->op.kind, v, type); } } case_end; -- cgit v1.2.3 From ef73a284e3e438a25a4e329d59057cfa8cddf44c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 22 Oct 2021 14:12:48 +0100 Subject: Fix check_remove_expr_info --- src/checker.cpp | 9 ++++++++- src/llvm_backend_expr.cpp | 4 ++-- src/map.cpp | 40 ++++++++++++++++++++++------------------ src/parser.hpp | 2 +- 4 files changed, 33 insertions(+), 22 deletions(-) (limited to 'src/llvm_backend_expr.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index d3c0080de..ec20d45d6 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1111,9 +1111,15 @@ void check_set_expr_info(CheckerContext *c, Ast *expr, AddressingMode mode, Type void check_remove_expr_info(CheckerContext *c, Ast *e) { if (c->untyped != nullptr) { map_remove(c->untyped, hash_pointer(e)); + if (map_get(c->untyped, hash_pointer(e)) != nullptr) { + map_remove(c->untyped, hash_pointer(e)); + GB_ASSERT(map_get(c->untyped, hash_pointer(e)) == nullptr); + } } else { + auto *untyped = &c->info->global_untyped; mutex_lock(&c->info->global_untyped_mutex); - map_remove(&c->info->global_untyped, hash_pointer(e)); + map_remove(untyped, hash_pointer(e)); + GB_ASSERT(map_get(untyped, hash_pointer(e)) == nullptr); mutex_unlock(&c->info->global_untyped_mutex); } } @@ -1191,6 +1197,7 @@ void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *ty prev_expr = expr; expr->tav.mode = mode; expr->tav.type = type; + if (mode == Addressing_Constant || mode == Addressing_Invalid) { expr->tav.value = value; } else if (mode == Addressing_Value && is_type_typeid(type)) { diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index caeae2fb0..6ad0e1191 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -2258,9 +2258,9 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { if (tv.value.kind != ExactValue_Invalid) { // NOTE(bill): The commented out code below is just for debug purposes only - // GB_ASSERT_MSG(!is_type_untyped(tv.type), "%s @ %s\n%s", type_to_string(tv.type), token_pos_to_string(expr_pos), expr_to_string(expr)); // if (is_type_untyped(type)) { - // gb_printf_err("%s %s\n", token_pos_to_string(expr_pos), expr_to_string(expr)); + // gb_printf_err("%s %s : %s @ %p\n", token_pos_to_string(expr_pos), expr_to_string(expr), type_to_string(expr->tav.type), expr); + // GB_PANIC("%s\n", type_to_string(tv.type)); // } // NOTE(bill): Short on constant values diff --git a/src/map.cpp b/src/map.cpp index 55eb4fbce..3a34764bf 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -114,16 +114,17 @@ gb_internal isize map__add_entry(Map *h, HashKey const &key) { template gb_internal MapFindResult map__find(Map *h, HashKey const &key) { MapFindResult fr = {-1, -1, -1}; - if (h->hashes.count > 0) { - fr.hash_index = key.key & (h->hashes.count-1); - fr.entry_index = h->hashes.data[fr.hash_index]; - while (fr.entry_index >= 0) { - if (hash_key_equal(h->entries.data[fr.entry_index].key, key)) { - return fr; - } - fr.entry_prev = fr.entry_index; - fr.entry_index = h->entries.data[fr.entry_index].next; + if (h->hashes.count == 0) { + return fr; + } + fr.hash_index = key.key & (h->hashes.count-1); + fr.entry_index = h->hashes.data[fr.hash_index]; + while (fr.entry_index >= 0) { + if (hash_key_equal(h->entries.data[fr.entry_index].key, key)) { + return fr; } + fr.entry_prev = fr.entry_index; + fr.entry_index = h->entries.data[fr.entry_index].next; } return fr; } @@ -131,16 +132,17 @@ gb_internal MapFindResult map__find(Map *h, HashKey const &key) { template gb_internal MapFindResult map__find_from_entry(Map *h, MapEntry *e) { MapFindResult fr = {-1, -1, -1}; - if (h->hashes.count > 0) { - fr.hash_index = e->key.key & (h->hashes.count-1); - fr.entry_index = h->hashes.data[fr.hash_index]; - while (fr.entry_index >= 0) { - if (&h->entries.data[fr.entry_index] == e) { - return fr; - } - fr.entry_prev = fr.entry_index; - fr.entry_index = h->entries.data[fr.entry_index].next; + if (h->hashes.count == 0) { + return fr; + } + fr.hash_index = e->key.key & (h->hashes.count-1); + fr.entry_index = h->hashes.data[fr.hash_index]; + while (fr.entry_index >= 0) { + if (&h->entries.data[fr.entry_index] == e) { + return fr; } + fr.entry_prev = fr.entry_index; + fr.entry_index = h->entries.data[fr.entry_index].next; } return fr; } @@ -246,6 +248,8 @@ void map__erase(Map *h, MapFindResult const &fr) { return; } h->entries.data[fr.entry_index] = h->entries.data[h->entries.count-1]; + array_pop(&h->entries); + last = map__find(h, h->entries.data[fr.entry_index].key); if (last.entry_prev >= 0) { h->entries.data[last.entry_prev].next = fr.entry_index; diff --git a/src/parser.hpp b/src/parser.hpp index f1779bdbc..8acc3f419 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -28,9 +28,9 @@ enum AddressingMode : u8 { }; struct TypeAndValue { + Type * type; AddressingMode mode; bool is_lhs; // Debug info - Type * type; ExactValue value; }; -- cgit v1.2.3 From c9effb9b9f6dd0400e2396fd2aa6a97e06a14638 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 22 Oct 2021 14:37:27 +0100 Subject: Correct ternary if expression type determination --- src/check_expr.cpp | 23 ++++++++++++++--------- src/check_stmt.cpp | 2 -- src/checker.cpp | 12 +++++++----- src/llvm_backend_expr.cpp | 6 ------ 4 files changed, 21 insertions(+), 22 deletions(-) (limited to 'src/llvm_backend_expr.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index a3554f3ea..275210c6c 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -837,8 +837,6 @@ void check_assignment(CheckerContext *c, Operand *operand, Type *type, String co if (operand->mode == Addressing_Type && is_type_typeid(type)) { add_type_info_type(c, operand->type); add_type_and_value(c->info, operand->expr, Addressing_Value, type, exact_value_typeid(operand->type)); - } else { - convert_to_typed(c, operand, type); } } else { gbString expr_str = expr_to_string(operand->expr); @@ -3226,9 +3224,9 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) { case Basic_UntypedNil: if (is_type_any(target_type)) { - target_type = t_untyped_nil; + // target_type = t_untyped_nil; } else if (is_type_cstring(target_type)) { - target_type = t_untyped_nil; + // target_type = t_untyped_nil; } else if (!type_has_nil(target_type)) { operand->mode = Addressing_Invalid; convert_untyped_error(c, operand, target_type); @@ -3376,6 +3374,14 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) { } break; } + + if (is_type_any(target_type) && is_type_untyped(operand->type)) { + if (is_type_untyped_nil(operand->type) && is_type_untyped_undef(operand->type)) { + + } else { + target_type = default_type(operand->type); + } + } update_untyped_expr_type(c, operand->expr, target_type, true); operand->type = target_type; @@ -6743,15 +6749,14 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type return kind; } - Type *type = x.type; - if (is_type_untyped_nil(type) || is_type_untyped_undef(type)) { - type = y.type; + o->type = x.type; + if (is_type_untyped_nil(o->type) || is_type_untyped_undef(o->type)) { + o->type = y.type; } - o->type = x.type; o->mode = Addressing_Value; o->expr = node; - if (type_hint != nullptr && is_type_untyped(type)) { + if (type_hint != nullptr && is_type_untyped(o->type)) { if (check_cast_internal(c, &x, type_hint) && check_cast_internal(c, &y, type_hint)) { convert_to_typed(c, o, type_hint); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 4dbc76578..103ffa071 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1728,8 +1728,6 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { Entity *e = pt->results->Tuple.variables[i]; Operand *o = &operands[i]; check_assignment(ctx, o, e->type, str_lit("return statement")); - convert_to_typed(ctx, o, e->type); - if (is_type_untyped(o->type)) { update_untyped_expr_type(ctx, o->expr, e->type, true); } diff --git a/src/checker.cpp b/src/checker.cpp index ec20d45d6..b1b148a84 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1111,10 +1111,7 @@ void check_set_expr_info(CheckerContext *c, Ast *expr, AddressingMode mode, Type void check_remove_expr_info(CheckerContext *c, Ast *e) { if (c->untyped != nullptr) { map_remove(c->untyped, hash_pointer(e)); - if (map_get(c->untyped, hash_pointer(e)) != nullptr) { - map_remove(c->untyped, hash_pointer(e)); - GB_ASSERT(map_get(c->untyped, hash_pointer(e)) == nullptr); - } + GB_ASSERT(map_get(c->untyped, hash_pointer(e)) == nullptr); } else { auto *untyped = &c->info->global_untyped; mutex_lock(&c->info->global_untyped_mutex); @@ -1196,7 +1193,12 @@ void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *ty while (prev_expr != expr) { prev_expr = expr; expr->tav.mode = mode; - expr->tav.type = type; + if (type != nullptr && expr->tav.type != nullptr && + is_type_any(type) && is_type_untyped(expr->tav.type)) { + // ignore + } else { + expr->tav.type = type; + } if (mode == Addressing_Constant || mode == Addressing_Invalid) { expr->tav.value = value; diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 6ad0e1191..214da9e10 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -762,12 +762,6 @@ lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) { case Token_Xor: case Token_AndNot: { Type *type = default_type(tv.type); - if (is_type_typed(be->left->tav.type) && is_type_untyped(be->right->tav.type)) { - be->right->tav.type = be->left->tav.type; - } else if (is_type_untyped(be->left->tav.type) && is_type_typed(be->right->tav.type)) { - be->left->tav.type = type_of_expr(be->right); - } - lbValue left = lb_build_expr(p, be->left); lbValue right = lb_build_expr(p, be->right); return lb_emit_arith(p, be->op.kind, left, right, type); -- cgit v1.2.3