From aaaff9b66ca10edd9cf76bb24463a7b16095325e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 6 Sep 2023 17:33:38 +0100 Subject: [PATCH] Fix bug: Disallow non-specialized polymorphic in typeid assignment --- src/check_expr.cpp | 18 ++++++++++++++---- src/checker.cpp | 7 ++++++- src/llvm_backend_const.cpp | 7 +++++-- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index a0d3c24bf..abcb7fd72 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -629,6 +629,9 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand if (operand->mode == Addressing_Type) { if (is_type_typeid(type)) { + if (is_type_polymorphic(operand->type)) { + return -1; + } add_type_info_type(c, operand->type); return 4; } @@ -1118,10 +1121,17 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ LIT(context_name)); break; case Addressing_Type: - error(operand->expr, - "Cannot assign '%s' which is a type in %.*s", - op_type_str, - LIT(context_name)); + if (is_type_polymorphic(operand->type)) { + error(operand->expr, + "Cannot assign '%s' which is a polymorphic type in %.*s", + op_type_str, + LIT(context_name)); + } else { + error(operand->expr, + "Cannot assign '%s' which is a type in %.*s", + op_type_str, + LIT(context_name)); + } break; default: // TODO(bill): is this a good enough error message? diff --git a/src/checker.cpp b/src/checker.cpp index a8efa39ab..18d403d80 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1922,6 +1922,12 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { for_array(i, bt->Union.variants) { add_type_info_type_internal(c, bt->Union.variants[i]); } + if (bt->Union.scope != nullptr) { + for (auto const &entry : bt->Union.scope->elements) { + Entity *e = entry.value; + add_type_info_type_internal(c, e->type); + } + } break; case Type_Struct: @@ -2265,7 +2271,6 @@ gb_internal void add_dependency_to_set(Checker *c, Entity *entity) { if (decl == nullptr) { return; } - for (Type *t : decl->type_info_deps) { add_min_dep_type_info(c, t); } diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 5c390a370..01b0528d0 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -1094,8 +1094,11 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo } if (is_constant) { LLVMValueRef elem_value = lb_const_value(m, tav.type, tav.value, allow_local).value; - GB_ASSERT(LLVMIsConstant(elem_value)); - values[index] = LLVMConstInsertValue(values[index], elem_value, idx_list, idx_list_len); + if (LLVMIsConstant(elem_value)) { + values[index] = LLVMConstInsertValue(values[index], elem_value, idx_list, idx_list_len); + } else { + is_constant = false; + } } } }