diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-09-29 19:14:42 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-09-29 19:14:42 +0100 |
commit | fa1039760e8c1a0c7a2a722160bd3d71a4736e61 (patch) | |
tree | 3749fc4f1e8e0cdccdde2c131dfca30b3b07917c /src/evalfunc.c | |
parent | 9f573a8df02d9f699a43d2afbd1d2841d700b9ad (diff) |
patch 9.0.0623: error for modifying a const is not detected at compile timev9.0.0623
Problem: Error for modifying a const is not detected at compile time.
Solution: Add TTFLAG_CONST and check for it in add() and extend().
Diffstat (limited to 'src/evalfunc.c')
-rw-r--r-- | src/evalfunc.c | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/src/evalfunc.c b/src/evalfunc.c index 857f211a21..211e12ce4b 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -222,6 +222,22 @@ check_arg_type( } /* + * 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 @@ arg_list_or_blob(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) } /* + * 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 @@ arg_list_or_dict(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) } /* + * 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_number[] = {arg_list_any, arg_number}; 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 arg24_count[] = {arg_string_or_list_or_dict, NULL, arg_bool, a 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 @@ static funcentry_T global_functions[] = 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}, |