aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2020-06-10 15:37:50 +0100
committergingerBill <bill@gingerbill.org>2020-06-10 15:37:50 +0100
commit57b09b2ffbd1021d29e43fdc1f27da43f1b4ed23 (patch)
treeace60d87ae2fc67f35267ac954a58f1b2b91b711 /src
parente86fde3cb16d2977054aa727c32cd4efcb1bd8a7 (diff)
Fix #439
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.cpp19
-rw-r--r--src/ir.cpp29
-rw-r--r--src/ir_print.cpp4
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;