comparison src/vim9compile.c @ 31551:67d9fbe516a3 v9.0.1108

patch 9.0.1108: type error when using "any" type and adding to float Commit: https://github.com/vim/vim/commit/c6951a76a58663ef8a773d340f2260da7455643c Author: Bram Moolenaar <Bram@vim.org> Date: Thu Dec 29 20:56:24 2022 +0000 patch 9.0.1108: type error when using "any" type and adding to float Problem: Type error when using "any" type and adding a number to a float. Solution: Accept both a number and a float. (closes https://github.com/vim/vim/issues/11753)
author Bram Moolenaar <Bram@vim.org>
date Thu, 29 Dec 2022 22:00:04 +0100
parents cd5247f4da06
children aee868b9229a
comparison
equal deleted inserted replaced
31550:aadc3446d666 31551:67d9fbe516a3
449 */ 449 */
450 int 450 int
451 need_type_where( 451 need_type_where(
452 type_T *actual, 452 type_T *actual,
453 type_T *expected, 453 type_T *expected,
454 int number_ok, // expect VAR_FLOAT but VAR_NUMBER is OK
454 int offset, 455 int offset,
455 where_T where, 456 where_T where,
456 cctx_T *cctx, 457 cctx_T *cctx,
457 int silent, 458 int silent,
458 int actual_is_const) 459 int actual_is_const)
478 return OK; 479 return OK;
479 480
480 // If the actual type can be the expected type add a runtime check. 481 // If the actual type can be the expected type add a runtime check.
481 if (!actual_is_const && ret == MAYBE && use_typecheck(actual, expected)) 482 if (!actual_is_const && ret == MAYBE && use_typecheck(actual, expected))
482 { 483 {
483 generate_TYPECHECK(cctx, expected, offset, 484 generate_TYPECHECK(cctx, expected, number_ok, offset,
484 where.wt_variable, where.wt_index); 485 where.wt_variable, where.wt_index);
485 return OK; 486 return OK;
486 } 487 }
487 488
488 if (!silent) 489 if (!silent)
492 493
493 int 494 int
494 need_type( 495 need_type(
495 type_T *actual, 496 type_T *actual,
496 type_T *expected, 497 type_T *expected,
498 int number_ok, // when expected is float number is also OK
497 int offset, 499 int offset,
498 int arg_idx, 500 int arg_idx,
499 cctx_T *cctx, 501 cctx_T *cctx,
500 int silent, 502 int silent,
501 int actual_is_const) 503 int actual_is_const)
502 { 504 {
503 where_T where = WHERE_INIT; 505 where_T where = WHERE_INIT;
504 506
505 where.wt_index = arg_idx; 507 where.wt_index = arg_idx;
506 return need_type_where(actual, expected, offset, where, 508 return need_type_where(actual, expected, number_ok, offset, where,
507 cctx, silent, actual_is_const); 509 cctx, silent, actual_is_const);
508 } 510 }
509 511
510 /* 512 /*
511 * Set type of variable "lvar" to "type". If the variable is a constant then 513 * Set type of variable "lvar" to "type". If the variable is a constant then
1998 lhs->lhs_type = cctx->ctx_type_stack.ga_len == 0 ? &t_void 2000 lhs->lhs_type = cctx->ctx_type_stack.ga_len == 0 ? &t_void
1999 : get_type_on_stack(cctx, 0); 2001 : get_type_on_stack(cctx, 0);
2000 // now we can properly check the type 2002 // now we can properly check the type
2001 if (rhs_type != NULL && lhs->lhs_type->tt_member != NULL 2003 if (rhs_type != NULL && lhs->lhs_type->tt_member != NULL
2002 && rhs_type != &t_void 2004 && rhs_type != &t_void
2003 && need_type(rhs_type, lhs->lhs_type->tt_member, -2, 0, cctx, 2005 && need_type(rhs_type, lhs->lhs_type->tt_member, FALSE,
2004 FALSE, FALSE) == FAIL) 2006 -2, 0, cctx, FALSE, FALSE) == FAIL)
2005 return FAIL; 2007 return FAIL;
2006 } 2008 }
2007 else 2009 else
2008 generate_loadvar(cctx, lhs); 2010 generate_loadvar(cctx, lhs);
2009 return OK; 2011 return OK;
2088 type_T *type; 2090 type_T *type;
2089 2091
2090 if (range) 2092 if (range)
2091 { 2093 {
2092 type = get_type_on_stack(cctx, 1); 2094 type = get_type_on_stack(cctx, 1);
2093 if (need_type(type, &t_number, 2095 if (need_type(type, &t_number, FALSE,
2094 -2, 0, cctx, FALSE, FALSE) == FAIL) 2096 -2, 0, cctx, FALSE, FALSE) == FAIL)
2095 return FAIL; 2097 return FAIL;
2096 } 2098 }
2097 type = get_type_on_stack(cctx, 0); 2099 type = get_type_on_stack(cctx, 0);
2098 if ((dest_type != VAR_BLOB && type->tt_type != VAR_SPECIAL) 2100 if ((dest_type != VAR_BLOB && type->tt_type != VAR_SPECIAL)
2099 && need_type(type, &t_number, 2101 && need_type(type, &t_number, FALSE,
2100 -1, 0, cctx, FALSE, FALSE) == FAIL) 2102 -1, 0, cctx, FALSE, FALSE) == FAIL)
2101 return FAIL; 2103 return FAIL;
2102 } 2104 }
2103 } 2105 }
2104 2106
2355 if (stacktype->tt_type == VAR_VOID) 2357 if (stacktype->tt_type == VAR_VOID)
2356 { 2358 {
2357 emsg(_(e_cannot_use_void_value)); 2359 emsg(_(e_cannot_use_void_value));
2358 goto theend; 2360 goto theend;
2359 } 2361 }
2360 if (need_type(stacktype, &t_list_any, -1, 0, cctx, 2362 if (need_type(stacktype, &t_list_any, FALSE, -1, 0, cctx,
2361 FALSE, FALSE) == FAIL) 2363 FALSE, FALSE) == FAIL)
2362 goto theend; 2364 goto theend;
2363 // If a constant list was used we can check the length right here. 2365 // If a constant list was used we can check the length right here.
2364 needed_list_len = semicolon ? var_count - 1 : var_count; 2366 needed_list_len = semicolon ? var_count - 1 : var_count;
2365 if (instr->ga_len > 0) 2367 if (instr->ga_len > 0)
2422 goto theend; 2424 goto theend;
2423 if (heredoc) 2425 if (heredoc)
2424 { 2426 {
2425 SOURCING_LNUM = start_lnum; 2427 SOURCING_LNUM = start_lnum;
2426 if (lhs.lhs_has_type 2428 if (lhs.lhs_has_type
2427 && need_type(&t_list_string, lhs.lhs_type, 2429 && need_type(&t_list_string, lhs.lhs_type, FALSE,
2428 -1, 0, cctx, FALSE, FALSE) == FAIL) 2430 -1, 0, cctx, FALSE, FALSE) == FAIL)
2429 goto theend; 2431 goto theend;
2430 } 2432 }
2431 else 2433 else
2432 { 2434 {
2547 // member type. Not for "list[:] =". 2549 // member type. Not for "list[:] =".
2548 if (lhs.lhs_has_index 2550 if (lhs.lhs_has_index
2549 && !has_list_index(var_start + lhs.lhs_varlen, 2551 && !has_list_index(var_start + lhs.lhs_varlen,
2550 cctx)) 2552 cctx))
2551 use_type = lhs.lhs_member_type; 2553 use_type = lhs.lhs_member_type;
2552 if (need_type_where(rhs_type, use_type, -1, where, 2554 if (need_type_where(rhs_type, use_type, FALSE, -1,
2553 cctx, FALSE, is_const) == FAIL) 2555 where, cctx, FALSE, is_const) == FAIL)
2554 goto theend; 2556 goto theend;
2555 } 2557 }
2556 } 2558 }
2557 else 2559 else
2558 { 2560 {
2563 // Also: can assign a number to a float. 2565 // Also: can assign a number to a float.
2564 if ((lhs_type == &t_number_or_string 2566 if ((lhs_type == &t_number_or_string
2565 || lhs_type == &t_float) 2567 || lhs_type == &t_float)
2566 && rhs_type->tt_type == VAR_NUMBER) 2568 && rhs_type->tt_type == VAR_NUMBER)
2567 lhs_type = &t_number; 2569 lhs_type = &t_number;
2568 if (*p != '=' && need_type(rhs_type, lhs_type, 2570 if (*p != '=' && need_type(rhs_type, lhs_type, FALSE,
2569 -1, 0, cctx, FALSE, FALSE) == FAIL) 2571 -1, 0, cctx, FALSE, FALSE) == FAIL)
2570 goto theend; 2572 goto theend;
2571 } 2573 }
2572 } 2574 }
2573 else if (cmdidx == CMD_final) 2575 else if (cmdidx == CMD_final)
2620 expected = lhs.lhs_member_type; 2622 expected = lhs.lhs_member_type;
2621 stacktype = get_type_on_stack(cctx, 0); 2623 stacktype = get_type_on_stack(cctx, 0);
2622 if ( 2624 if (
2623 // If variable is float operation with number is OK. 2625 // If variable is float operation with number is OK.
2624 !(expected == &t_float && (stacktype == &t_number 2626 !(expected == &t_float && (stacktype == &t_number
2625 || stacktype == &t_number_bool)) && 2627 || stacktype == &t_number_bool))
2626 need_type(stacktype, expected, -1, 0, cctx, 2628 && need_type(stacktype, expected, TRUE, -1, 0, cctx,
2627 FALSE, FALSE) == FAIL) 2629 FALSE, FALSE) == FAIL)
2628 goto theend; 2630 goto theend;
2629 } 2631 }
2630 2632
2631 if (*op == '.') 2633 if (*op == '.')
3102 { 3104 {
3103 did_set_arg_type = TRUE; 3105 did_set_arg_type = TRUE;
3104 ufunc->uf_arg_types[arg_idx] = val_type; 3106 ufunc->uf_arg_types[arg_idx] = val_type;
3105 } 3107 }
3106 else if (need_type_where(val_type, ufunc->uf_arg_types[arg_idx], 3108 else if (need_type_where(val_type, ufunc->uf_arg_types[arg_idx],
3107 -1, where, &cctx, FALSE, FALSE) == FAIL) 3109 FALSE, -1, where, &cctx, FALSE, FALSE) == FAIL)
3108 goto erret; 3110 goto erret;
3109 3111
3110 if (generate_STORE(&cctx, ISN_STORE, i - count - off, NULL) == FAIL) 3112 if (generate_STORE(&cctx, ISN_STORE, i - count - off, NULL) == FAIL)
3111 goto erret; 3113 goto erret;
3112 3114