From 57b09b2ffbd1021d29e43fdc1f27da43f1b4ed23 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 10 Jun 2020 15:37:50 +0100 Subject: [PATCH] Fix #439 --- src/check_expr.cpp | 19 ++++++++++++++++--- src/ir.cpp | 29 +++++++++++++++++++++++++++-- src/ir_print.cpp | 4 ++-- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index a52295298..059ed917d 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -7760,6 +7760,20 @@ bool check_range(CheckerContext *c, Ast *node, Operand *x, Operand *y, ExactValu return true; } +bool check_is_operand_compound_lit_constant(CheckerContext *c, Operand *o) { + Ast *expr = unparen_expr(o->expr); + if (expr != nullptr) { + Entity *e = strip_entity_wrapping(entity_from_expr(expr)); + if (e != nullptr && e->kind == Entity_Procedure) { + return true; + } + if (expr->kind == Ast_ProcLit) { + add_type_and_value(c->info, expr, Addressing_Constant, type_of_expr(expr), exact_value_procedure(expr)); + return true; + } + } + return o->mode == Addressing_Constant; +} ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { @@ -7780,7 +7794,6 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type c->state_flags = out; } - ExprKind kind = Expr_Stmt; o->mode = Addressing_Invalid; @@ -8242,7 +8255,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type is_constant = false; } if (is_constant) { - is_constant = o.mode == Addressing_Constant; + is_constant = check_is_operand_compound_lit_constant(c, &o); } check_assignment(c, &o, field->type, str_lit("structure literal")); @@ -8277,7 +8290,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type is_constant = false; } if (is_constant) { - is_constant = o.mode == Addressing_Constant; + is_constant = check_is_operand_compound_lit_constant(c, &o); } check_assignment(c, &o, field->type, str_lit("structure literal")); diff --git a/src/ir.cpp b/src/ir.cpp index 1c2f8df37..9ded36ca4 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -523,6 +523,7 @@ struct irAddr { }; Type *ir_type(irValue *value); +irValue *ir_gen_anonymous_proc_lit(irModule *m, String prefix_name, Ast *expr, irProcedure *proc = nullptr); irAddr ir_addr(irValue *addr) { irAddr v = {irAddr_Default, addr}; @@ -1614,7 +1615,27 @@ irDefer ir_add_defer_proc(irProcedure *proc, isize scope_index, irValue *deferre } - +void ir_check_compound_lit_constant(irModule *m, Ast *expr) { + expr = unparen_expr(expr); + if (expr == nullptr) { + return; + } + if (expr->kind == Ast_CompoundLit) { + ast_node(cl, CompoundLit, expr); + for_array(i, cl->elems) { + Ast *elem = cl->elems[i]; + if (elem->kind == Ast_FieldValue) { + ast_node(fv, FieldValue, elem); + ir_check_compound_lit_constant(m, fv->value); + } else { + ir_check_compound_lit_constant(m, elem); + } + } + } + if (expr->kind == Ast_ProcLit) { + ir_gen_anonymous_proc_lit(m, str_lit("_proclit"), expr); + } +} irValue *ir_add_module_constant(irModule *m, Type *type, ExactValue value) { gbAllocator a = ir_allocator(); @@ -1652,6 +1673,10 @@ irValue *ir_add_module_constant(irModule *m, Type *type, ExactValue value) { } } + if (value.kind == ExactValue_Compound) { + ir_check_compound_lit_constant(m, value.value_compound); + } + return ir_value_constant(type, value); } @@ -6504,7 +6529,7 @@ void ir_pop_target_list(irProcedure *proc) { -irValue *ir_gen_anonymous_proc_lit(irModule *m, String prefix_name, Ast *expr, irProcedure *proc = nullptr) { +irValue *ir_gen_anonymous_proc_lit(irModule *m, String prefix_name, Ast *expr, irProcedure *proc) { ast_node(pl, ProcLit, expr); // NOTE(bill): Generate a new name diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 9a7b1e113..fb09ad471 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -1294,7 +1294,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type * } case ExactValue_Procedure: { irValue **found = nullptr; - Ast *expr = value.value_procedure; + Ast *expr = unparen_expr(value.value_procedure); GB_ASSERT(expr != nullptr); if (expr->kind == Ast_ProcLit) { @@ -1304,7 +1304,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type * GB_ASSERT(e != nullptr); found = map_get(&m->values, hash_entity(e)); } - GB_ASSERT(found != nullptr); + GB_ASSERT_MSG(found != nullptr, "%s", expr_to_string(expr)); irValue *val = *found; ir_print_value(f, m, val, type); break;