aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-06-16 14:03:12 +0100
committergingerBill <bill@gingerbill.org>2021-06-16 14:03:12 +0100
commitdbdc4471c2c7c9fcb477b09c1e6c7fe4256a95f7 (patch)
tree35a9797f9934540f80db48da83af3b0038c8bfa2 /src
parentaf95381bf8394c9edd392f019048fdc72c821ca5 (diff)
Fix double evaluation bug with selector call expressions `x->y(z)`
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.cpp31
1 files changed, 27 insertions, 4 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index fefb5a9ef..16a574b3d 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -4331,16 +4331,29 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) {
}
if (error_code != 0) {
err = CallArgumentError_TooManyArguments;
- char const *err_fmt = "Too many arguments for '%s', expected %td arguments";
+ char const *err_fmt = "Too many arguments for '%s', expected %td arguments, got %td";
if (error_code < 0) {
err = CallArgumentError_TooFewArguments;
- err_fmt = "Too few arguments for '%s', expected %td arguments";
+ err_fmt = "Too few arguments for '%s', expected %td arguments, got %td";
}
if (show_error) {
gbString proc_str = expr_to_string(ce->proc);
- error(call, err_fmt, proc_str, param_count_excluding_defaults);
- gb_string_free(proc_str);
+ defer (gb_string_free(proc_str));
+ error(call, err_fmt, proc_str, param_count_excluding_defaults, operands.count);
+
+ #if 0
+ error_line("\t");
+ for_array(i, operands) {
+ if (i > 0) {
+ error_line(", ");
+ }
+ gbString s = expr_to_string(operands[i].expr);
+ error_line("%s", s);
+ gb_string_free(s);
+ }
+ error_line("\n");
+ #endif
}
} else {
// NOTE(bill): Generate the procedure type for this generic instance
@@ -7564,6 +7577,16 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
//
// NOTE(bill, 2020-05-22): I'm going to regret this decision, ain't I?
+
+ if (se->modified_call) {
+ // Prevent double evaluation
+ o->expr = node;
+ o->type = node->tav.type;
+ o->value = node->tav.value;
+ o->mode = node->tav.mode;
+ return Expr_Expr;
+ }
+
bool allow_arrow_right_selector_expr;
allow_arrow_right_selector_expr = c->allow_arrow_right_selector_expr;
c->allow_arrow_right_selector_expr = true;