• R/O
  • SSH

vim: Commit

Mirror of the Vim source from https://github.com/vim/vim


Commit MetaInfo

Revision24bd79082d865060f616affd82eee5e614f5d519 (tree)
Time2021-07-22 04:45:04
AuthorBram Moolenaar <Bram@vim....>
CommiterBram Moolenaar

Log Message

patch 8.2.3196: Vim9: bool expression with numbers only fails at runtime

Commit: https://github.com/vim/vim/commit/05bd9785fd0fd0102ab64554307bff0ec0ae34c1
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Jul 21 21:37:28 2021 +0200

patch 8.2.3196: Vim9: bool expression with numbers only fails at runtime
Problem: Vim9: bool expression with numbers only fails at runtime.
Solution: Check constant to be bool at compile time. (closes https://github.com/vim/vim/issues/8603)

Change Summary

Incremental Difference

diff -r b2006e12af25 -r 24bd79082d86 src/testdir/test_vim9_expr.vim
--- a/src/testdir/test_vim9_expr.vim Wed Jul 21 20:45:05 2021 +0200
+++ b/src/testdir/test_vim9_expr.vim Wed Jul 21 21:45:04 2021 +0200
@@ -372,9 +372,9 @@
372372
373373 def Test_expr2_fails()
374374 var msg = "White space required before and after '||'"
375- call CheckDefAndScriptFailure(["var x = 1||2"], msg, 1)
376- call CheckDefAndScriptFailure(["var x = 1 ||2"], msg, 1)
377- call CheckDefAndScriptFailure(["var x = 1|| 2"], msg, 1)
375+ call CheckDefAndScriptFailure(["var x = 1||0"], msg, 1)
376+ call CheckDefAndScriptFailure(["var x = 1 ||0"], msg, 1)
377+ call CheckDefAndScriptFailure(["var x = 1|| 0"], msg, 1)
378378
379379 call CheckDefFailure(["var x = false || "], 'E1097:', 3)
380380 call CheckScriptFailure(['vim9script', "var x = false || "], 'E15:', 2)
@@ -386,8 +386,8 @@
386386
387387 call CheckDefAndScriptFailure2(["if 'yes' || 0", 'echo 0', 'endif'], 'E1012: Type mismatch; expected bool but got string', 'E1135: Using a String as a Bool', 1)
388388
389- # TODO: should fail at compile time
390- call CheckDefExecAndScriptFailure(["var x = 3 || 7"], 'E1023:', 1)
389+ call CheckDefAndScriptFailure2(["var x = 3 || false"], 'E1012:', 'E1023:', 1)
390+ call CheckDefAndScriptFailure2(["var x = false || 3"], 'E1012:', 'E1023:', 1)
391391
392392 call CheckDefAndScriptFailure(["if 3"], 'E1023:', 1)
393393 call CheckDefExecAndScriptFailure(['var x = 3', 'if x', 'endif'], 'E1023:', 2)
@@ -505,15 +505,15 @@
505505
506506 def Test_expr3_fails()
507507 var msg = "White space required before and after '&&'"
508- CheckDefAndScriptFailure(["var x = 1&&2"], msg, 1)
509- CheckDefAndScriptFailure(["var x = 1 &&2"], msg, 1)
510- CheckDefAndScriptFailure(["var x = 1&& 2"], msg, 1)
508+ CheckDefAndScriptFailure(["var x = 1&&0"], msg, 1)
509+ CheckDefAndScriptFailure(["var x = 1 &&0"], msg, 1)
510+ CheckDefAndScriptFailure(["var x = 1&& 0"], msg, 1)
511511 var lines =<< trim END
512512 var x = 1
513- &&2
513+ &&0
514514 # comment
515515 END
516- CheckDefAndScriptFailure(lines, 'E1004: White space required before and after ''&&'' at "&&2"', 2)
516+ CheckDefAndScriptFailure(lines, 'E1004: White space required before and after ''&&'' at "&&0"', 2)
517517
518518 g:vals = []
519519 CheckDefAndScriptFailure2(["if 'yes' && 0", 'echo 0', 'endif'], 'E1012: Type mismatch; expected bool but got string', 'E1135: Using a String as a Bool', 1)
@@ -525,7 +525,14 @@
525525 && true
526526 endif
527527 END
528- CheckDefExecAndScriptFailure(lines, 'E1023:', 1)
528+ CheckDefAndScriptFailure2(lines, 'E1012:', 'E1023:', 1)
529+
530+ lines =<< trim END
531+ if true
532+ && 3
533+ endif
534+ END
535+ CheckDefAndScriptFailure2(lines, 'E1012:', 'E1023:', 2)
529536
530537 lines =<< trim END
531538 if 'yes'
diff -r b2006e12af25 -r 24bd79082d86 src/version.c
--- a/src/version.c Wed Jul 21 20:45:05 2021 +0200
+++ b/src/version.c Wed Jul 21 21:45:04 2021 +0200
@@ -756,6 +756,8 @@
756756 static int included_patches[] =
757757 { /* Add new patch number below this line */
758758 /**/
759+ 3196,
760+/**/
759761 3195,
760762 /**/
761763 3194,
diff -r b2006e12af25 -r 24bd79082d86 src/vim9compile.c
--- a/src/vim9compile.c Wed Jul 21 20:45:05 2021 +0200
+++ b/src/vim9compile.c Wed Jul 21 21:45:04 2021 +0200
@@ -2796,6 +2796,24 @@
27962796 }
27972797
27982798 /*
2799+ * Check that the last item of "ppconst" is a bool.
2800+ */
2801+ static int
2802+check_ppconst_bool(ppconst_T *ppconst)
2803+{
2804+ if (ppconst->pp_used > 0)
2805+ {
2806+ typval_T *tv = &ppconst->pp_tv[ppconst->pp_used - 1];
2807+ where_T where;
2808+
2809+ where.wt_index = 0;
2810+ where.wt_variable = FALSE;
2811+ return check_typval_type(&t_bool, tv, where);
2812+ }
2813+ return OK;
2814+}
2815+
2816+/*
27992817 * Clear ppconst constants. Used when failing.
28002818 */
28012819 static void
@@ -5138,6 +5156,7 @@
51385156 long save_sourcing_lnum;
51395157 int start_ctx_lnum = cctx->ctx_lnum;
51405158 int save_lnum;
5159+ int status;
51415160
51425161 if (next != NULL)
51435162 {
@@ -5152,28 +5171,29 @@
51525171 return FAIL;
51535172 }
51545173
5155- // TODO: use ppconst if the value is a constant and check
5156- // evaluating to bool
5157- generate_ppconst(cctx, ppconst);
5158-
5159- // Every part must evaluate to a bool.
51605174 save_sourcing_lnum = SOURCING_LNUM;
51615175 SOURCING_LNUM = start_lnum;
51625176 save_lnum = cctx->ctx_lnum;
51635177 cctx->ctx_lnum = start_ctx_lnum;
5164- if (bool_on_stack(cctx) == FAIL)
5165- {
5166- cctx->ctx_lnum = save_lnum;
5167- ga_clear(&end_ga);
5168- return FAIL;
5178+
5179+ status = check_ppconst_bool(ppconst);
5180+ if (status == OK)
5181+ {
5182+ // TODO: use ppconst if the value is a constant
5183+ generate_ppconst(cctx, ppconst);
5184+
5185+ // Every part must evaluate to a bool.
5186+ status = (bool_on_stack(cctx));
5187+ if (status == OK)
5188+ status = ga_grow(&end_ga, 1);
51695189 }
51705190 cctx->ctx_lnum = save_lnum;
5171-
5172- if (ga_grow(&end_ga, 1) == FAIL)
5191+ if (status == FAIL)
51735192 {
51745193 ga_clear(&end_ga);
51755194 return FAIL;
51765195 }
5196+
51775197 *(((int *)end_ga.ga_data) + end_ga.ga_len) = instr->ga_len;
51785198 ++end_ga.ga_len;
51795199 generate_JUMP(cctx, opchar == '|'
@@ -5196,6 +5216,12 @@
51965216
51975217 p = may_peek_next_line(cctx, *arg, &next);
51985218 }
5219+
5220+ if (check_ppconst_bool(ppconst) == FAIL)
5221+ {
5222+ ga_clear(&end_ga);
5223+ return FAIL;
5224+ }
51995225 generate_ppconst(cctx, ppconst);
52005226
52015227 // Every part must evaluate to a bool.
Show on old repository browser