diff options
Diffstat (limited to 'src/check_expr.cpp')
| -rw-r--r-- | src/check_expr.cpp | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 1552b1ef5..e0e74a3aa 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5144,8 +5144,20 @@ gb_internal bool check_assignment_arguments(CheckerContext *ctx, Array<Operand> } +typedef u32 UnpackFlags; +enum UnpackFlag : u32 { + UnpackFlag_None = 0, + UnpackFlag_AllowOk = 1<<0, + UnpackFlag_IsVariadic = 1<<1, + UnpackFlag_AllowUndef = 1<<2, +}; + + +gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array<Operand> *operands, Slice<Ast *> const &rhs, UnpackFlags flags) { + bool allow_ok = (flags & UnpackFlag_AllowOk) != 0; + bool is_variadic = (flags & UnpackFlag_IsVariadic) != 0; + bool allow_undef = (flags & UnpackFlag_AllowUndef) != 0; -gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array<Operand> *operands, Slice<Ast *> const &rhs, bool allow_ok, bool is_variadic) { bool optional_ok = false; isize tuple_index = 0; for_array(i, rhs) { @@ -5184,7 +5196,13 @@ gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize } } - check_expr_base(c, &o, rhs[i], type_hint); + if (allow_undef && rhs[i] != nullptr && rhs[i]->kind == Ast_Undef) { + o.type = t_untyped_undef; + o.mode = Addressing_Value; + o.expr = rhs[i]; + } else { + check_expr_base(c, &o, rhs[i], type_hint); + } if (o.mode == Addressing_NoValue) { error_operand_no_value(&o); o.mode = Addressing_Invalid; @@ -5968,7 +5986,7 @@ gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *op lhs = populate_proc_parameter_list(c, proc_type, &lhs_count, &is_variadic); } if (operand->mode != Addressing_ProcGroup) { - check_unpack_arguments(c, lhs, lhs_count, &operands, args, false, is_variadic); + check_unpack_arguments(c, lhs, lhs_count, &operands, args, is_variadic ? UnpackFlag_IsVariadic : UnpackFlag_None); } } @@ -6025,7 +6043,7 @@ gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *op isize lhs_count = -1; bool is_variadic = false; lhs = populate_proc_parameter_list(c, e->type, &lhs_count, &is_variadic); - check_unpack_arguments(c, lhs, lhs_count, &operands, args, false, is_variadic); + check_unpack_arguments(c, lhs, lhs_count, &operands, args, is_variadic ? UnpackFlag_IsVariadic : UnpackFlag_None); CallArgumentData data = {}; CallArgumentError err = call_checker(c, call, e->type, e, operands, CallArgumentMode_ShowErrors, &data); @@ -6101,7 +6119,7 @@ gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *op } - check_unpack_arguments(c, lhs, lhs_count, &operands, args, false, false); + check_unpack_arguments(c, lhs, lhs_count, &operands, args, UnpackFlag_None); if (lhs != nullptr) { gb_free(heap_allocator(), lhs); @@ -6462,7 +6480,7 @@ gb_internal CallArgumentError check_polymorphic_record_type(CheckerContext *c, O lhs_count = params->variables.count; } - check_unpack_arguments(c, lhs, lhs_count, &operands, ce->args, false, false); + check_unpack_arguments(c, lhs, lhs_count, &operands, ce->args, UnpackFlag_None); } } @@ -9583,6 +9601,7 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast case_ast_node(u, Undef, node); o->mode = Addressing_Value; o->type = t_untyped_undef; + error(node, "Use of --- outside of variable declaration"); case_end; |