patch 9.0.0623: error for modifying a const is not detected at compile time
Problem: Error for modifying a const is not detected at compile time.
Solution: Add TTFLAG_CONST and check for it in add() and extend().
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 857f211..211e12c 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -222,6 +222,22 @@
}
/*
+ * Give an error if "type" is a constant.
+ */
+ int
+arg_type_modifiable(type_T *type, int arg_idx)
+{
+ char *tofree;
+
+ if ((type->tt_flags & TTFLAG_CONST) == 0)
+ return OK;
+ semsg(_(e_argument_nr_trying_to_modify_const_str),
+ arg_idx, type_name(type, &tofree));
+ vim_free(tofree);
+ return FAIL;
+}
+
+/*
* Check "type" is a float or a number.
*/
static int
@@ -324,6 +340,20 @@
}
/*
+ * Check "type" is a modifiable list of 'any' or a blob.
+ */
+ static int
+arg_list_or_blob_mod(
+ type_T *type,
+ type_T *decl_type,
+ argcontext_T *context)
+{
+ if (arg_list_or_blob(type, decl_type, context) == FAIL)
+ return FAIL;
+ return arg_type_modifiable(type, context->arg_idx + 1);
+}
+
+/*
* Check "type" is a string or a number
*/
static int
@@ -468,6 +498,20 @@
}
/*
+ * Check "type" is a list of 'any' or a dict of 'any'. And modifiable.
+ */
+ static int
+arg_list_or_dict_mod(
+ type_T *type,
+ type_T *decl_type,
+ argcontext_T *context)
+{
+ if (arg_list_or_dict(type, decl_type, context) == FAIL)
+ return FAIL;
+ return arg_type_modifiable(type, context->arg_idx + 1);
+}
+
+/*
* Check "type" is a list of 'any' or a dict of 'any' or a blob.
*/
static int
@@ -979,7 +1023,7 @@
static argcheck_T arg2_list_any_string[] = {arg_list_any, arg_string};
static argcheck_T arg2_list_number[] = {arg_list_number, arg_list_number};
static argcheck_T arg2_list_number_bool[] = {arg_list_number, arg_bool};
-static argcheck_T arg2_listblob_item[] = {arg_list_or_blob, arg_item_of_prev};
+static argcheck_T arg2_listblobmod_item[] = {arg_list_or_blob_mod, arg_item_of_prev};
static argcheck_T arg2_lnum[] = {arg_lnum, arg_lnum};
static argcheck_T arg2_lnum_number[] = {arg_lnum, arg_number};
static argcheck_T arg2_number[] = {arg_number, arg_number};
@@ -1036,7 +1080,7 @@
static argcheck_T arg13_cursor[] = {arg_cursor1, arg_number, arg_number};
static argcheck_T arg12_deepcopy[] = {NULL, arg_bool};
static argcheck_T arg12_execute[] = {arg_string_or_list_string, arg_string};
-static argcheck_T arg23_extend[] = {arg_list_or_dict, arg_same_as_prev, arg_extend3};
+static argcheck_T arg23_extend[] = {arg_list_or_dict_mod, arg_same_as_prev, arg_extend3};
static argcheck_T arg23_extendnew[] = {arg_list_or_dict, arg_same_struct_as_prev, arg_extend3};
static argcheck_T arg23_get[] = {arg_get1, arg_string_or_nr, NULL};
static argcheck_T arg14_glob[] = {arg_string, arg_bool, arg_bool, arg_bool};
@@ -1554,7 +1598,7 @@
ret_any, f_abs},
{"acos", 1, 1, FEARG_1, arg1_float_or_nr,
ret_float, f_acos},
- {"add", 2, 2, FEARG_1, arg2_listblob_item,
+ {"add", 2, 2, FEARG_1, arg2_listblobmod_item,
ret_first_arg, f_add},
{"and", 2, 2, FEARG_1, arg2_number,
ret_number, f_and},