mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 8.2.4103: Vim9: variable declared in for loop not initialzed
Problem: Vim9: variable declared in for loop not initialzed. Solution: Always initialze the variable. (closes #9535)
This commit is contained in:
@@ -63,6 +63,7 @@ int generate_UNPACK(cctx_T *cctx, int var_count, int semicolon);
|
|||||||
int generate_cmdmods(cctx_T *cctx, cmdmod_T *cmod);
|
int generate_cmdmods(cctx_T *cctx, cmdmod_T *cmod);
|
||||||
int generate_undo_cmdmods(cctx_T *cctx);
|
int generate_undo_cmdmods(cctx_T *cctx);
|
||||||
int generate_store_var(cctx_T *cctx, assign_dest_T dest, int opt_flags, int vimvaridx, int scriptvar_idx, int scriptvar_sid, type_T *type, char_u *name);
|
int generate_store_var(cctx_T *cctx, assign_dest_T dest, int opt_flags, int vimvaridx, int scriptvar_idx, int scriptvar_sid, type_T *type, char_u *name);
|
||||||
|
int inside_loop_scope(cctx_T *cctx);
|
||||||
int generate_store_lhs(cctx_T *cctx, lhs_T *lhs, int instr_count, int is_decl);
|
int generate_store_lhs(cctx_T *cctx, lhs_T *lhs, int instr_count, int is_decl);
|
||||||
void may_generate_prof_end(cctx_T *cctx, int prof_lnum);
|
void may_generate_prof_end(cctx_T *cctx, int prof_lnum);
|
||||||
void delete_instr(isn_T *isn);
|
void delete_instr(isn_T *isn);
|
||||||
|
@@ -587,6 +587,41 @@ def Test_assign_index()
|
|||||||
CheckDefFailure(lines, 'E1012: Type mismatch; expected list<number> but got dict<unknown>', 2)
|
CheckDefFailure(lines, 'E1012: Type mismatch; expected list<number> but got dict<unknown>', 2)
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def Test_init_in_for_loop()
|
||||||
|
var lines =<< trim END
|
||||||
|
var l: list<number> = []
|
||||||
|
for i in [3, 4]
|
||||||
|
var n: number
|
||||||
|
add(l, n)
|
||||||
|
n = 123
|
||||||
|
endfor
|
||||||
|
assert_equal([0, 0], l)
|
||||||
|
END
|
||||||
|
CheckDefAndScriptSuccess(lines)
|
||||||
|
|
||||||
|
lines =<< trim END
|
||||||
|
var l: list<number> = []
|
||||||
|
for i in [3, 4]
|
||||||
|
var n: number = 0
|
||||||
|
add(l, n)
|
||||||
|
n = 123
|
||||||
|
endfor
|
||||||
|
assert_equal([0, 0], l)
|
||||||
|
END
|
||||||
|
CheckDefAndScriptSuccess(lines)
|
||||||
|
|
||||||
|
lines =<< trim END
|
||||||
|
var l: list<number> = []
|
||||||
|
for i in [3, 4]
|
||||||
|
var n: number = 3
|
||||||
|
add(l, n)
|
||||||
|
n = 123
|
||||||
|
endfor
|
||||||
|
assert_equal([3, 3], l)
|
||||||
|
END
|
||||||
|
CheckDefAndScriptSuccess(lines)
|
||||||
|
enddef
|
||||||
|
|
||||||
def Test_extend_list()
|
def Test_extend_list()
|
||||||
var lines =<< trim END
|
var lines =<< trim END
|
||||||
var l1: list<number>
|
var l1: list<number>
|
||||||
|
@@ -750,6 +750,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
4103,
|
||||||
/**/
|
/**/
|
||||||
4102,
|
4102,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -2256,12 +2256,17 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
|||||||
case VAR_VOID:
|
case VAR_VOID:
|
||||||
case VAR_INSTR:
|
case VAR_INSTR:
|
||||||
case VAR_SPECIAL: // cannot happen
|
case VAR_SPECIAL: // cannot happen
|
||||||
// This is skipped for local variables, they are
|
// This is skipped for local variables, they are always
|
||||||
// always initialized to zero.
|
// initialized to zero. But in a "for" or "while" loop
|
||||||
if (lhs.lhs_dest == dest_local)
|
// the value may have been changed.
|
||||||
|
if (lhs.lhs_dest == dest_local
|
||||||
|
&& !inside_loop_scope(cctx))
|
||||||
skip_store = TRUE;
|
skip_store = TRUE;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
instr_count = instr->ga_len;
|
||||||
generate_PUSHNR(cctx, 0);
|
generate_PUSHNR(cctx, 0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1845,6 +1845,25 @@ generate_store_var(
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return TRUE when inside a "for" or "while" loop.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
inside_loop_scope(cctx_T *cctx)
|
||||||
|
{
|
||||||
|
scope_T *scope = cctx->ctx_scope;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (scope == NULL)
|
||||||
|
break;
|
||||||
|
if (scope->se_type == FOR_SCOPE || scope->se_type == WHILE_SCOPE)
|
||||||
|
return TRUE;
|
||||||
|
scope = scope->se_outer;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
generate_store_lhs(cctx_T *cctx, lhs_T *lhs, int instr_count, int is_decl)
|
generate_store_lhs(cctx_T *cctx, lhs_T *lhs, int instr_count, int is_decl)
|
||||||
{
|
{
|
||||||
@@ -1869,8 +1888,9 @@ generate_store_lhs(cctx_T *cctx, lhs_T *lhs, int instr_count, int is_decl)
|
|||||||
varnumber_T val = isn->isn_arg.number;
|
varnumber_T val = isn->isn_arg.number;
|
||||||
garray_T *stack = &cctx->ctx_type_stack;
|
garray_T *stack = &cctx->ctx_type_stack;
|
||||||
|
|
||||||
if (val == 0 && is_decl)
|
if (val == 0 && is_decl && !inside_loop_scope(cctx))
|
||||||
{
|
{
|
||||||
|
// zero is the default value, no need to do anything
|
||||||
--instr->ga_len;
|
--instr->ga_len;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user