comparison src/vim9compile.c @ 24796:7c1375eb1636 v8.2.2936

patch 8.2.2936: Vim9: converting number to bool uses wrong stack offset Commit: https://github.com/vim/vim/commit/5fa9b24440d677c1aa00084d0cf84638b1e1a0d5 Author: Bram Moolenaar <Bram@vim.org> Date: Fri Jun 4 21:00:32 2021 +0200 patch 8.2.2936: Vim9: converting number to bool uses wrong stack offset Problem: Vim9: converting number to bool uses wrong stack offset. (Salman Halim) Solution: Include the offset in the 2BOOL command.
author Bram Moolenaar <Bram@vim.org>
date Fri, 04 Jun 2021 21:15:04 +0200
parents 7464d4c927f5
children a8d64f1a223b
comparison
equal deleted inserted replaced
24795:05a337d1fe73 24796:7c1375eb1636
575 } 575 }
576 576
577 /* 577 /*
578 * If type at "offset" isn't already VAR_STRING then generate ISN_2STRING. 578 * If type at "offset" isn't already VAR_STRING then generate ISN_2STRING.
579 * But only for simple types. 579 * But only for simple types.
580 */ 580 * When "tolerant" is TRUE convert most types to string, e.g. a List.
581 static int 581 */
582 may_generate_2STRING(int offset, cctx_T *cctx) 582 static int
583 may_generate_2STRING(int offset, int tolerant, cctx_T *cctx)
583 { 584 {
584 isn_T *isn; 585 isn_T *isn;
585 isntype_T isntype = ISN_2STRING; 586 isntype_T isntype = ISN_2STRING;
586 garray_T *stack = &cctx->ctx_type_stack; 587 garray_T *stack = &cctx->ctx_type_stack;
587 type_T **type; 588 type_T **type;
604 case VAR_ANY: 605 case VAR_ANY:
605 case VAR_UNKNOWN: 606 case VAR_UNKNOWN:
606 isntype = ISN_2STRING_ANY; 607 isntype = ISN_2STRING_ANY;
607 break; 608 break;
608 609
610 // conversion possible when tolerant
611 case VAR_LIST:
612 if (tolerant)
613 {
614 isntype = ISN_2STRING_ANY;
615 break;
616 }
617 // FALLTHROUGH
618
609 // conversion not possible 619 // conversion not possible
610 case VAR_VOID: 620 case VAR_VOID:
611 case VAR_BLOB: 621 case VAR_BLOB:
612 case VAR_FUNC: 622 case VAR_FUNC:
613 case VAR_PARTIAL: 623 case VAR_PARTIAL:
614 case VAR_LIST:
615 case VAR_DICT: 624 case VAR_DICT:
616 case VAR_JOB: 625 case VAR_JOB:
617 case VAR_CHANNEL: 626 case VAR_CHANNEL:
618 case VAR_INSTR: 627 case VAR_INSTR:
619 to_string_error((*type)->tt_type); 628 to_string_error((*type)->tt_type);
621 } 630 }
622 631
623 *type = &t_string; 632 *type = &t_string;
624 if ((isn = generate_instr(cctx, isntype)) == NULL) 633 if ((isn = generate_instr(cctx, isntype)) == NULL)
625 return FAIL; 634 return FAIL;
626 isn->isn_arg.number = offset; 635 isn->isn_arg.tostring.offset = offset;
636 isn->isn_arg.tostring.tolerant = tolerant;
627 637
628 return OK; 638 return OK;
629 } 639 }
630 640
631 static int 641 static int
884 return OK; 894 return OK;
885 } 895 }
886 896
887 /* 897 /*
888 * Generate an ISN_2BOOL instruction. 898 * Generate an ISN_2BOOL instruction.
889 */ 899 * "offset" is the offset in the type stack.
890 static int 900 */
891 generate_2BOOL(cctx_T *cctx, int invert) 901 static int
902 generate_2BOOL(cctx_T *cctx, int invert, int offset)
892 { 903 {
893 isn_T *isn; 904 isn_T *isn;
894 garray_T *stack = &cctx->ctx_type_stack; 905 garray_T *stack = &cctx->ctx_type_stack;
895 906
896 RETURN_OK_IF_SKIP(cctx); 907 RETURN_OK_IF_SKIP(cctx);
897 if ((isn = generate_instr(cctx, ISN_2BOOL)) == NULL) 908 if ((isn = generate_instr(cctx, ISN_2BOOL)) == NULL)
898 return FAIL; 909 return FAIL;
899 isn->isn_arg.number = invert; 910 isn->isn_arg.tobool.invert = invert;
911 isn->isn_arg.tobool.offset = offset;
900 912
901 // type becomes bool 913 // type becomes bool
902 ((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_bool; 914 ((type_T **)stack->ga_data)[stack->ga_len + offset] = &t_bool;
903 915
904 return OK; 916 return OK;
905 } 917 }
906 918
907 /* 919 /*
1006 if (expected == &t_bool && actual != &t_bool 1018 if (expected == &t_bool && actual != &t_bool
1007 && (actual->tt_flags & TTFLAG_BOOL_OK)) 1019 && (actual->tt_flags & TTFLAG_BOOL_OK))
1008 { 1020 {
1009 // Using "0", "1" or the result of an expression with "&&" or "||" as a 1021 // Using "0", "1" or the result of an expression with "&&" or "||" as a
1010 // boolean is OK but requires a conversion. 1022 // boolean is OK but requires a conversion.
1011 generate_2BOOL(cctx, FALSE); 1023 generate_2BOOL(cctx, FALSE, offset);
1012 return OK; 1024 return OK;
1013 } 1025 }
1014 1026
1015 where.wt_index = arg_idx; 1027 where.wt_index = arg_idx;
1016 where.wt_variable = FALSE; 1028 where.wt_variable = FALSE;
2780 if (need_type(*typep, &t_dict_any, -2, 0, cctx, 2792 if (need_type(*typep, &t_dict_any, -2, 0, cctx,
2781 FALSE, FALSE) == FAIL) 2793 FALSE, FALSE) == FAIL)
2782 return FAIL; 2794 return FAIL;
2783 *typep = &t_any; 2795 *typep = &t_any;
2784 } 2796 }
2785 if (may_generate_2STRING(-1, cctx) == FAIL) 2797 if (may_generate_2STRING(-1, FALSE, cctx) == FAIL)
2786 return FAIL; 2798 return FAIL;
2787 if (generate_instr_drop(cctx, ISN_MEMBER, 1) == FAIL) 2799 if (generate_instr_drop(cctx, ISN_MEMBER, 1) == FAIL)
2788 return FAIL; 2800 return FAIL;
2789 } 2801 }
2790 else if (vartype == VAR_STRING) 2802 else if (vartype == VAR_STRING)
3623 isn->isn_type = ISN_PUSHS; 3635 isn->isn_type = ISN_PUSHS;
3624 isn->isn_arg.string = vim_strsave((char_u *)buf); 3636 isn->isn_arg.string = vim_strsave((char_u *)buf);
3625 } 3637 }
3626 if (isn->isn_type == ISN_PUSHS) 3638 if (isn->isn_type == ISN_PUSHS)
3627 key = isn->isn_arg.string; 3639 key = isn->isn_arg.string;
3628 else if (may_generate_2STRING(-1, cctx) == FAIL) 3640 else if (may_generate_2STRING(-1, FALSE, cctx) == FAIL)
3629 return FAIL; 3641 return FAIL;
3630 *arg = skipwhite(*arg); 3642 *arg = skipwhite(*arg);
3631 if (**arg != ']') 3643 if (**arg != ']')
3632 { 3644 {
3633 emsg(_(e_missing_matching_bracket_after_dict_key)); 3645 emsg(_(e_missing_matching_bracket_after_dict_key));
4024 { 4036 {
4025 if (p[-1] == '!') 4037 if (p[-1] == '!')
4026 invert = !invert; 4038 invert = !invert;
4027 --p; 4039 --p;
4028 } 4040 }
4029 if (generate_2BOOL(cctx, invert) == FAIL) 4041 if (generate_2BOOL(cctx, invert, -1) == FAIL)
4030 return FAIL; 4042 return FAIL;
4031 } 4043 }
4032 } 4044 }
4033 *end = p; 4045 *end = p;
4034 return OK; 4046 return OK;
4847 { 4859 {
4848 generate_ppconst(cctx, ppconst); 4860 generate_ppconst(cctx, ppconst);
4849 ppconst->pp_is_const = FALSE; 4861 ppconst->pp_is_const = FALSE;
4850 if (*op == '.') 4862 if (*op == '.')
4851 { 4863 {
4852 if (may_generate_2STRING(-2, cctx) == FAIL 4864 if (may_generate_2STRING(-2, FALSE, cctx) == FAIL
4853 || may_generate_2STRING(-1, cctx) == FAIL) 4865 || may_generate_2STRING(-1, FALSE, cctx) == FAIL)
4854 return FAIL; 4866 return FAIL;
4855 generate_instr_drop(cctx, ISN_CONCAT, 1); 4867 generate_instr_drop(cctx, ISN_CONCAT, 1);
4856 } 4868 }
4857 else 4869 else
4858 generate_two_op(cctx, op); 4870 generate_two_op(cctx, op);
6418 if (dest_type == VAR_DICT && range) 6430 if (dest_type == VAR_DICT && range)
6419 { 6431 {
6420 emsg(e_cannot_use_range_with_dictionary); 6432 emsg(e_cannot_use_range_with_dictionary);
6421 return FAIL; 6433 return FAIL;
6422 } 6434 }
6423 if (dest_type == VAR_DICT && may_generate_2STRING(-1, cctx) == FAIL) 6435 if (dest_type == VAR_DICT
6436 && may_generate_2STRING(-1, FALSE, cctx) == FAIL)
6424 return FAIL; 6437 return FAIL;
6425 if (dest_type == VAR_LIST || dest_type == VAR_BLOB) 6438 if (dest_type == VAR_LIST || dest_type == VAR_BLOB)
6426 { 6439 {
6427 type_T *type; 6440 type_T *type;
6428 6441
8381 8394
8382 if (compile_expr0(&p, cctx) == FAIL) 8395 if (compile_expr0(&p, cctx) == FAIL)
8383 return NULL; 8396 return NULL;
8384 if (cctx->ctx_skip == SKIP_YES) 8397 if (cctx->ctx_skip == SKIP_YES)
8385 return p; 8398 return p;
8386 if (may_generate_2STRING(-1, cctx) == FAIL) 8399 if (may_generate_2STRING(-1, FALSE, cctx) == FAIL)
8387 return NULL; 8400 return NULL;
8388 if (generate_instr_drop(cctx, ISN_THROW, 1) == NULL) 8401 if (generate_instr_drop(cctx, ISN_THROW, 1) == NULL)
8389 return NULL; 8402 return NULL;
8390 8403
8391 return p; 8404 return p;
8616 ++count; 8629 ++count;
8617 } 8630 }
8618 p += 2; 8631 p += 2;
8619 if (compile_expr0(&p, cctx) == FAIL) 8632 if (compile_expr0(&p, cctx) == FAIL)
8620 return NULL; 8633 return NULL;
8621 may_generate_2STRING(-1, cctx); 8634 may_generate_2STRING(-1, TRUE, cctx);
8622 ++count; 8635 ++count;
8623 p = skipwhite(p); 8636 p = skipwhite(p);
8624 if (*p != '`') 8637 if (*p != '`')
8625 { 8638 {
8626 emsg(_(e_missing_backtick)); 8639 emsg(_(e_missing_backtick));