From 0c35752d04f70408a3c560d5b3edbafcaddff302 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 18 Jul 2021 14:43:43 +0200 Subject: patch 8.2.3176: Vim9: no type error for comparing number with string Problem: Vim9: no type error for comparing number with string. Solution: Add a runtime type check. (closes #8571) --- src/errors.h | 4 ++-- src/testdir/test_vim9_expr.vim | 23 +++++++++++++++++++++++ src/typval.c | 16 ++++++++++++++-- src/version.c | 2 ++ 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/errors.h b/src/errors.h index 46de733bc6..35d1487338 100644 --- a/src/errors.h +++ b/src/errors.h @@ -381,8 +381,8 @@ EXTERN char e_mismatched_endfunction[] INIT(= N_("E1151: Mismatched endfunction")); EXTERN char e_mismatched_enddef[] INIT(= N_("E1152: Mismatched enddef")); -EXTERN char e_invalid_operation_for_bool[] - INIT(= N_("E1153: Invalid operation for bool")); +EXTERN char e_invalid_operation_for_str[] + INIT(= N_("E1153: Invalid operation for %s")); EXTERN char e_divide_by_zero[] INIT(= N_("E1154: Divide by zero")); EXTERN char e_cannot_define_autocommands_for_all_events[] diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim index cd6ffa4463..e7c08f4af0 100644 --- a/src/testdir/test_vim9_expr.vim +++ b/src/testdir/test_vim9_expr.vim @@ -660,13 +660,36 @@ def Test_expr4_equal() CheckDefExecAndScriptFailure(["var x: any = true", 'echo x == ""'], 'E1072: Cannot compare bool with string', 2) CheckDefExecAndScriptFailure2(["var x: any = 99", 'echo x == true'], 'E1138', 'E1072:', 2) CheckDefExecAndScriptFailure2(["var x: any = 'a'", 'echo x == 99'], 'E1030:', 'E1072:', 2) +enddef +def Test_expr4_wrong_type() for op in ['>', '>=', '<', '<=', '=~', '!~'] CheckDefExecAndScriptFailure([ "var a: any = 'a'", 'var b: any = true', 'echo a ' .. op .. ' b'], 'E1072:', 3) endfor + for op in ['>', '>=', '<', '<='] + CheckDefExecAndScriptFailure2([ + "var n: any = 2", + 'echo n ' .. op .. ' "3"'], 'E1030:', 'E1072:', 2) + endfor + for op in ['=~', '!~'] + CheckDefExecAndScriptFailure([ + "var n: any = 2", + 'echo n ' .. op .. ' "3"'], 'E1072:', 2) + endfor + + CheckDefAndScriptFailure([ + 'echo v:none == true'], 'E1072:', 1) + CheckDefAndScriptFailure([ + 'echo false >= true'], 'E1072:', 1) + CheckDefExecAndScriptFailure([ + "var n: any = v:none", + 'echo n == true'], 'E1072:', 2) + CheckDefExecAndScriptFailure([ + "var n: any = v:none", + 'echo n < true'], 'E1072:', 2) enddef " test != comperator diff --git a/src/typval.c b/src/typval.c index 03891c806d..9d5903f649 100644 --- a/src/typval.c +++ b/src/typval.c @@ -937,7 +937,9 @@ typval_compare( } } else if (in_vim9script() && (typ1->v_type == VAR_BOOL - || typ2->v_type == VAR_BOOL)) + || typ2->v_type == VAR_BOOL + || (typ1->v_type == VAR_SPECIAL + && typ2->v_type == VAR_SPECIAL))) { if (typ1->v_type != typ2->v_type) { @@ -955,13 +957,23 @@ typval_compare( case EXPR_ISNOT: case EXPR_NEQUAL: n1 = (n1 != n2); break; default: - emsg(_(e_invalid_operation_for_bool)); + semsg(_(e_invalid_operation_for_str), + vartype_name(typ1->v_type)); clear_tv(typ1); return FAIL; } } else { + if (in_vim9script() + && ((typ1->v_type != VAR_STRING && typ1->v_type != VAR_SPECIAL) + || (typ2->v_type != VAR_STRING && typ2->v_type != VAR_SPECIAL))) + { + semsg(_(e_cannot_compare_str_with_str), + vartype_name(typ1->v_type), vartype_name(typ2->v_type)); + clear_tv(typ1); + return FAIL; + } s1 = tv_get_string_buf(typ1, buf1); s2 = tv_get_string_buf(typ2, buf2); if (type != EXPR_MATCH && type != EXPR_NOMATCH) diff --git a/src/version.c b/src/version.c index 8b674d3773..c1a4f3f8fa 100644 --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 3176, /**/ 3175, /**/ -- cgit v1.2.3