diff options
| author | gingerBill <bill@gingerbill.org> | 2020-11-10 14:48:57 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2020-11-10 14:48:57 +0000 |
| commit | ee3b3fe6a3424d84cda26b1cddc764694ac49e7a (patch) | |
| tree | 3319a19fda0d40b35518e52bc1b899028687eede /src/check_expr.cpp | |
| parent | eea3a1ecd38bda7b942c621001705a79ac6024e3 (diff) | |
Fix `typeid_of` bug
Diffstat (limited to 'src/check_expr.cpp')
| -rw-r--r-- | src/check_expr.cpp | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 01e971ac7..a8e7550a1 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -4343,7 +4343,6 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 add_type_info_type(c, t); - t = base_type(t); if (o.mode != Addressing_Type) { error(expr, "Expected a type for 'typeid_of'"); return false; @@ -4351,6 +4350,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 operand->mode = Addressing_Value; operand->type = t_typeid; + operand->value = exact_value_typeid(t); break; } @@ -7843,7 +7843,7 @@ void check_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *t) { err_str = "used as a value"; break; case Addressing_Type: - err_str = "is not an expression but a"; + err_str = "is not an expression but a type"; break; case Addressing_Builtin: err_str = "must be called"; @@ -9108,6 +9108,9 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type } is_constant = false; { // Checker values + bool key_is_typeid = is_type_typeid(t->Map.key); + bool value_is_typeid = is_type_typeid(t->Map.value); + for_array(i, cl->elems) { Ast *elem = cl->elems[i]; if (elem->kind != Ast_FieldValue) { @@ -9115,13 +9118,22 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type continue; } ast_node(fv, FieldValue, elem); - check_expr_with_type_hint(c, o, fv->field, t->Map.key); + + if (key_is_typeid) { + check_expr_or_type(c, o, fv->field, t->Map.key); + } else { + check_expr_with_type_hint(c, o, fv->field, t->Map.key); + } check_assignment(c, o, t->Map.key, str_lit("map literal")); if (o->mode == Addressing_Invalid) { continue; } - check_expr_with_type_hint(c, o, fv->value, t->Map.value); + if (value_is_typeid) { + check_expr_or_type(c, o, fv->value, t->Map.value); + } else { + check_expr_with_type_hint(c, o, fv->value, t->Map.value); + } check_assignment(c, o, t->Map.value, str_lit("map literal")); } } @@ -9677,7 +9689,11 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type if (is_type_map(t)) { Operand key = {}; - check_expr_with_type_hint(c, &key, ie->index, t->Map.key); + if (is_type_typeid(t->Map.key)) { + check_expr_or_type(c, &key, ie->index, t->Map.key); + } else { + check_expr_with_type_hint(c, &key, ie->index, t->Map.key); + } check_assignment(c, &key, t->Map.key, str_lit("map index")); if (key.mode == Addressing_Invalid) { o->mode = Addressing_Invalid; |