comparison src/vim9compile.c @ 23640:8dcb2255ff9a v8.2.2362

patch 8.2.2362: Vim9: check of builtin function argument type is incomplete Commit: https://github.com/vim/vim/commit/351ead09dd365ebdee2bfa27ab22542d4920c779 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jan 16 16:07:01 2021 +0100 patch 8.2.2362: Vim9: check of builtin function argument type is incomplete Problem: Vim9: check of builtin function argument type is incomplete. Solution: Use need_type() instead of check_arg_type().
author Bram Moolenaar <Bram@vim.org>
date Sat, 16 Jan 2021 16:15:04 +0100
parents 455ad460ff4f
children c8f26523d7d7
comparison
equal deleted inserted replaced
23639:a93ecfa78aef 23640:8dcb2255ff9a
876 * - "actual" is a type that can be "expected" type: add a runtime check; or 876 * - "actual" is a type that can be "expected" type: add a runtime check; or
877 * - return FAIL. 877 * - return FAIL.
878 * If "actual_is_const" is TRUE then the type won't change at runtime, do not 878 * If "actual_is_const" is TRUE then the type won't change at runtime, do not
879 * generate a TYPECHECK. 879 * generate a TYPECHECK.
880 */ 880 */
881 static int 881 int
882 need_type( 882 need_type(
883 type_T *actual, 883 type_T *actual,
884 type_T *expected, 884 type_T *expected,
885 int offset, 885 int offset,
886 int arg_idx,
886 cctx_T *cctx, 887 cctx_T *cctx,
887 int silent, 888 int silent,
888 int actual_is_const) 889 int actual_is_const)
889 { 890 {
890 if (expected == &t_bool && actual != &t_bool 891 if (expected == &t_bool && actual != &t_bool
894 // boolean is OK but requires a conversion. 895 // boolean is OK but requires a conversion.
895 generate_2BOOL(cctx, FALSE); 896 generate_2BOOL(cctx, FALSE);
896 return OK; 897 return OK;
897 } 898 }
898 899
899 if (check_type(expected, actual, FALSE, 0) == OK) 900 if (check_type(expected, actual, FALSE, arg_idx) == OK)
900 return OK; 901 return OK;
901 902
902 // If the actual type can be the expected type add a runtime check. 903 // If the actual type can be the expected type add a runtime check.
903 // If it's a constant a runtime check makes no sense. 904 // If it's a constant a runtime check makes no sense.
904 if (!actual_is_const && use_typecheck(actual, expected)) 905 if (!actual_is_const && use_typecheck(actual, expected))
906 generate_TYPECHECK(cctx, expected, offset); 907 generate_TYPECHECK(cctx, expected, offset);
907 return OK; 908 return OK;
908 } 909 }
909 910
910 if (!silent) 911 if (!silent)
911 type_mismatch(expected, actual); 912 arg_type_mismatch(expected, actual, arg_idx);
912 return FAIL; 913 return FAIL;
913 } 914 }
914 915
915 /* 916 /*
916 * Check that the top of the type stack has a type that can be used as a 917 * Check that the top of the type stack has a type that can be used as a
929 if (type == &t_any || type == &t_number) 930 if (type == &t_any || type == &t_number)
930 // Number 0 and 1 are OK to use as a bool. "any" could also be a bool. 931 // Number 0 and 1 are OK to use as a bool. "any" could also be a bool.
931 // This requires a runtime type check. 932 // This requires a runtime type check.
932 return generate_COND2BOOL(cctx); 933 return generate_COND2BOOL(cctx);
933 934
934 return need_type(type, &t_bool, -1, cctx, FALSE, FALSE); 935 return need_type(type, &t_bool, -1, 0, cctx, FALSE, FALSE);
935 } 936 }
936 937
937 /* 938 /*
938 * Generate an ISN_PUSHNR instruction. 939 * Generate an ISN_PUSHNR instruction.
939 */ 940 */
1611 1612
1612 if (argcount > 0) 1613 if (argcount > 0)
1613 { 1614 {
1614 // Check the types of the arguments. 1615 // Check the types of the arguments.
1615 argtypes = ((type_T **)stack->ga_data) + stack->ga_len - argcount; 1616 argtypes = ((type_T **)stack->ga_data) + stack->ga_len - argcount;
1616 if (internal_func_check_arg_types(argtypes, func_idx, argcount) == FAIL) 1617 if (internal_func_check_arg_types(argtypes, func_idx, argcount,
1618 cctx) == FAIL)
1617 return FAIL; 1619 return FAIL;
1618 if (internal_func_is_map(func_idx)) 1620 if (internal_func_is_map(func_idx))
1619 maptype = *argtypes; 1621 maptype = *argtypes;
1620 } 1622 }
1621 1623
1654 1656
1655 // Caller already checked that list_type is a list. 1657 // Caller already checked that list_type is a list.
1656 list_type = ((type_T **)stack->ga_data)[stack->ga_len - 2]; 1658 list_type = ((type_T **)stack->ga_data)[stack->ga_len - 2];
1657 item_type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; 1659 item_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
1658 expected = list_type->tt_member; 1660 expected = list_type->tt_member;
1659 if (need_type(item_type, expected, -1, cctx, FALSE, FALSE) == FAIL) 1661 if (need_type(item_type, expected, -1, 0, cctx, FALSE, FALSE) == FAIL)
1660 return FAIL; 1662 return FAIL;
1661 1663
1662 if (generate_instr(cctx, ISN_LISTAPPEND) == NULL) 1664 if (generate_instr(cctx, ISN_LISTAPPEND) == NULL)
1663 return FAIL; 1665 return FAIL;
1664 1666
1676 garray_T *stack = &cctx->ctx_type_stack; 1678 garray_T *stack = &cctx->ctx_type_stack;
1677 type_T *item_type; 1679 type_T *item_type;
1678 1680
1679 // Caller already checked that blob_type is a blob. 1681 // Caller already checked that blob_type is a blob.
1680 item_type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; 1682 item_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
1681 if (need_type(item_type, &t_number, -1, cctx, FALSE, FALSE) == FAIL) 1683 if (need_type(item_type, &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL)
1682 return FAIL; 1684 return FAIL;
1683 1685
1684 if (generate_instr(cctx, ISN_BLOBAPPEND) == NULL) 1686 if (generate_instr(cctx, ISN_BLOBAPPEND) == NULL)
1685 return FAIL; 1687 return FAIL;
1686 1688
1731 // possibly a lambda or "...: any" 1733 // possibly a lambda or "...: any"
1732 expected = &t_any; 1734 expected = &t_any;
1733 else 1735 else
1734 expected = ufunc->uf_va_type->tt_member; 1736 expected = ufunc->uf_va_type->tt_member;
1735 actual = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i]; 1737 actual = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i];
1736 if (need_type(actual, expected, -argcount + i, cctx, 1738 if (need_type(actual, expected, -argcount + i, 0, cctx,
1737 TRUE, FALSE) == FAIL) 1739 TRUE, FALSE) == FAIL)
1738 { 1740 {
1739 arg_type_mismatch(expected, actual, i + 1); 1741 arg_type_mismatch(expected, actual, i + 1);
1740 return FAIL; 1742 return FAIL;
1741 } 1743 }
1848 if (varargs && i >= type->tt_argcount - 1) 1850 if (varargs && i >= type->tt_argcount - 1)
1849 expected = type->tt_args[ 1851 expected = type->tt_args[
1850 type->tt_argcount - 1]->tt_member; 1852 type->tt_argcount - 1]->tt_member;
1851 else 1853 else
1852 expected = type->tt_args[i]; 1854 expected = type->tt_args[i];
1853 if (need_type(actual, expected, offset, 1855 if (need_type(actual, expected, offset, 0,
1854 cctx, TRUE, FALSE) == FAIL) 1856 cctx, TRUE, FALSE) == FAIL)
1855 { 1857 {
1856 arg_type_mismatch(expected, actual, i + 1); 1858 arg_type_mismatch(expected, actual, i + 1);
1857 return FAIL; 1859 return FAIL;
1858 } 1860 }
3133 key = isn->isn_arg.string; 3135 key = isn->isn_arg.string;
3134 else 3136 else
3135 { 3137 {
3136 type_T *keytype = ((type_T **)stack->ga_data) 3138 type_T *keytype = ((type_T **)stack->ga_data)
3137 [stack->ga_len - 1]; 3139 [stack->ga_len - 1];
3138 if (need_type(keytype, &t_string, -1, cctx, 3140 if (need_type(keytype, &t_string, -1, 0, cctx,
3139 FALSE, FALSE) == FAIL) 3141 FALSE, FALSE) == FAIL)
3140 return FAIL; 3142 return FAIL;
3141 } 3143 }
3142 *arg = skipwhite(*arg); 3144 *arg = skipwhite(*arg);
3143 if (**arg != ']') 3145 if (**arg != ']')
3806 // If the index is a string, the variable must be a Dict. 3808 // If the index is a string, the variable must be a Dict.
3807 if (*typep == &t_any && valtype == &t_string) 3809 if (*typep == &t_any && valtype == &t_string)
3808 vtype = VAR_DICT; 3810 vtype = VAR_DICT;
3809 if (vtype == VAR_STRING || vtype == VAR_LIST || vtype == VAR_BLOB) 3811 if (vtype == VAR_STRING || vtype == VAR_LIST || vtype == VAR_BLOB)
3810 { 3812 {
3811 if (need_type(valtype, &t_number, -1, cctx, 3813 if (need_type(valtype, &t_number, -1, 0, cctx,
3812 FALSE, FALSE) == FAIL) 3814 FALSE, FALSE) == FAIL)
3813 return FAIL; 3815 return FAIL;
3814 if (is_slice) 3816 if (is_slice)
3815 { 3817 {
3816 valtype = ((type_T **)stack->ga_data)[stack->ga_len - 2]; 3818 valtype = ((type_T **)stack->ga_data)[stack->ga_len - 2];
3817 if (need_type(valtype, &t_number, -2, cctx, 3819 if (need_type(valtype, &t_number, -2, 0, cctx,
3818 FALSE, FALSE) == FAIL) 3820 FALSE, FALSE) == FAIL)
3819 return FAIL; 3821 return FAIL;
3820 } 3822 }
3821 } 3823 }
3822 3824
3834 // empty dict was used 3836 // empty dict was used
3835 *typep = &t_any; 3837 *typep = &t_any;
3836 } 3838 }
3837 else 3839 else
3838 { 3840 {
3839 if (need_type(*typep, &t_dict_any, -2, cctx, 3841 if (need_type(*typep, &t_dict_any, -2, 0, cctx,
3840 FALSE, FALSE) == FAIL) 3842 FALSE, FALSE) == FAIL)
3841 return FAIL; 3843 return FAIL;
3842 *typep = &t_any; 3844 *typep = &t_any;
3843 } 3845 }
3844 if (may_generate_2STRING(-1, cctx) == FAIL) 3846 if (may_generate_2STRING(-1, cctx) == FAIL)
4233 4235
4234 generate_ppconst(cctx, ppconst); 4236 generate_ppconst(cctx, ppconst);
4235 actual = ((type_T **)stack->ga_data)[stack->ga_len - 1]; 4237 actual = ((type_T **)stack->ga_data)[stack->ga_len - 1];
4236 if (check_type(want_type, actual, FALSE, 0) == FAIL) 4238 if (check_type(want_type, actual, FALSE, 0) == FAIL)
4237 { 4239 {
4238 if (need_type(actual, want_type, -1, cctx, FALSE, FALSE) == FAIL) 4240 if (need_type(actual, want_type, -1, 0, cctx, FALSE, FALSE) == FAIL)
4239 return FAIL; 4241 return FAIL;
4240 } 4242 }
4241 } 4243 }
4242 4244
4243 return OK; 4245 return OK;
4915 { 4917 {
4916 emsg(_(e_returning_value_in_function_without_return_type)); 4918 emsg(_(e_returning_value_in_function_without_return_type));
4917 return NULL; 4919 return NULL;
4918 } 4920 }
4919 if (need_type(stack_type, cctx->ctx_ufunc->uf_ret_type, -1, 4921 if (need_type(stack_type, cctx->ctx_ufunc->uf_ret_type, -1,
4920 cctx, FALSE, FALSE) == FAIL) 4922 0, cctx, FALSE, FALSE) == FAIL)
4921 return NULL; 4923 return NULL;
4922 } 4924 }
4923 } 4925 }
4924 } 4926 }
4925 else 4927 else
5829 5831
5830 lhs->lhs_type = stack->ga_len == 0 ? &t_void 5832 lhs->lhs_type = stack->ga_len == 0 ? &t_void
5831 : ((type_T **)stack->ga_data)[stack->ga_len - 1]; 5833 : ((type_T **)stack->ga_data)[stack->ga_len - 1];
5832 // now we can properly check the type 5834 // now we can properly check the type
5833 if (lhs->lhs_type->tt_member != NULL && rhs_type != &t_void 5835 if (lhs->lhs_type->tt_member != NULL && rhs_type != &t_void
5834 && need_type(rhs_type, lhs->lhs_type->tt_member, -2, cctx, 5836 && need_type(rhs_type, lhs->lhs_type->tt_member, -2, 0, cctx,
5835 FALSE, FALSE) == FAIL) 5837 FALSE, FALSE) == FAIL)
5836 return FAIL; 5838 return FAIL;
5837 } 5839 }
5838 else 5840 else
5839 generate_loadvar(cctx, lhs->lhs_dest, lhs->lhs_name, 5841 generate_loadvar(cctx, lhs->lhs_dest, lhs->lhs_name,
5974 if (stacktype->tt_type == VAR_VOID) 5976 if (stacktype->tt_type == VAR_VOID)
5975 { 5977 {
5976 emsg(_(e_cannot_use_void_value)); 5978 emsg(_(e_cannot_use_void_value));
5977 goto theend; 5979 goto theend;
5978 } 5980 }
5979 if (need_type(stacktype, &t_list_any, -1, cctx, 5981 if (need_type(stacktype, &t_list_any, -1, 0, cctx,
5980 FALSE, FALSE) == FAIL) 5982 FALSE, FALSE) == FAIL)
5981 goto theend; 5983 goto theend;
5982 // TODO: check the length of a constant list here 5984 // TODO: check the length of a constant list here
5983 generate_CHECKLEN(cctx, semicolon ? var_count - 1 : var_count, 5985 generate_CHECKLEN(cctx, semicolon ? var_count - 1 : var_count,
5984 semicolon); 5986 semicolon);
6121 type_T *use_type = lhs.lhs_lvar->lv_type; 6123 type_T *use_type = lhs.lhs_lvar->lv_type;
6122 6124
6123 // without operator check type here, otherwise below 6125 // without operator check type here, otherwise below
6124 if (lhs.lhs_has_index) 6126 if (lhs.lhs_has_index)
6125 use_type = lhs.lhs_member_type; 6127 use_type = lhs.lhs_member_type;
6126 if (need_type(rhs_type, use_type, -1, cctx, 6128 if (need_type(rhs_type, use_type, -1, 0, cctx,
6127 FALSE, is_const) == FAIL) 6129 FALSE, is_const) == FAIL)
6128 goto theend; 6130 goto theend;
6129 } 6131 }
6130 } 6132 }
6131 else if (*p != '=' && need_type(rhs_type, lhs.lhs_member_type, 6133 else if (*p != '=' && need_type(rhs_type, lhs.lhs_member_type,
6132 -1, cctx, FALSE, FALSE) == FAIL) 6134 -1, 0, cctx, FALSE, FALSE) == FAIL)
6133 goto theend; 6135 goto theend;
6134 } 6136 }
6135 else if (cmdidx == CMD_final) 6137 else if (cmdidx == CMD_final)
6136 { 6138 {
6137 emsg(_(e_final_requires_a_value)); 6139 emsg(_(e_final_requires_a_value));
6214 if ( 6216 if (
6215 #ifdef FEAT_FLOAT 6217 #ifdef FEAT_FLOAT
6216 // If variable is float operation with number is OK. 6218 // If variable is float operation with number is OK.
6217 !(expected == &t_float && stacktype == &t_number) && 6219 !(expected == &t_float && stacktype == &t_number) &&
6218 #endif 6220 #endif
6219 need_type(stacktype, expected, -1, cctx, 6221 need_type(stacktype, expected, -1, 0, cctx,
6220 FALSE, FALSE) == FAIL) 6222 FALSE, FALSE) == FAIL)
6221 goto theend; 6223 goto theend;
6222 6224
6223 if (*op == '.') 6225 if (*op == '.')
6224 { 6226 {
6923 arg_end = arg; 6925 arg_end = arg;
6924 6926
6925 // Now that we know the type of "var", check that it is a list, now or at 6927 // Now that we know the type of "var", check that it is a list, now or at
6926 // runtime. 6928 // runtime.
6927 vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1]; 6929 vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
6928 if (need_type(vartype, &t_list_any, -1, cctx, FALSE, FALSE) == FAIL) 6930 if (need_type(vartype, &t_list_any, -1, 0, cctx, FALSE, FALSE) == FAIL)
6929 { 6931 {
6930 drop_scope(cctx); 6932 drop_scope(cctx);
6931 return NULL; 6933 return NULL;
6932 } 6934 }
6933 6935