forked from aniani/vim
patch 8.2.3364: Vim9: crash when :for is skipped
Problem: Vim9: crash when :for is skipped. Solution: Skip more code generation. (Naruhiko Nishino, closes #8777)
This commit is contained in:
@@ -2552,6 +2552,70 @@ def Test_for_outside_of_function()
|
|||||||
delete('Xvim9for.vim')
|
delete('Xvim9for.vim')
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def Test_for_skipped_block()
|
||||||
|
# test skipped blocks at outside of function
|
||||||
|
var lines =<< trim END
|
||||||
|
var result = []
|
||||||
|
if true
|
||||||
|
for n in [1, 2]
|
||||||
|
result += [n]
|
||||||
|
endfor
|
||||||
|
else
|
||||||
|
for n in [3, 4]
|
||||||
|
result += [n]
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
assert_equal([1, 2], result)
|
||||||
|
|
||||||
|
result = []
|
||||||
|
if false
|
||||||
|
for n in [1, 2]
|
||||||
|
result += [n]
|
||||||
|
endfor
|
||||||
|
else
|
||||||
|
for n in [3, 4]
|
||||||
|
result += [n]
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
assert_equal([3, 4], result)
|
||||||
|
END
|
||||||
|
CheckDefAndScriptSuccess(lines)
|
||||||
|
|
||||||
|
# test skipped blocks at inside of function
|
||||||
|
lines =<< trim END
|
||||||
|
def DefTrue()
|
||||||
|
var result = []
|
||||||
|
if true
|
||||||
|
for n in [1, 2]
|
||||||
|
result += [n]
|
||||||
|
endfor
|
||||||
|
else
|
||||||
|
for n in [3, 4]
|
||||||
|
result += [n]
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
assert_equal([1, 2], result)
|
||||||
|
enddef
|
||||||
|
DefTrue()
|
||||||
|
|
||||||
|
def DefFalse()
|
||||||
|
var result = []
|
||||||
|
if false
|
||||||
|
for n in [1, 2]
|
||||||
|
result += [n]
|
||||||
|
endfor
|
||||||
|
else
|
||||||
|
for n in [3, 4]
|
||||||
|
result += [n]
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
assert_equal([3, 4], result)
|
||||||
|
enddef
|
||||||
|
DefFalse()
|
||||||
|
END
|
||||||
|
CheckDefAndScriptSuccess(lines)
|
||||||
|
enddef
|
||||||
|
|
||||||
def Test_for_loop()
|
def Test_for_loop()
|
||||||
var lines =<< trim END
|
var lines =<< trim END
|
||||||
var result = ''
|
var result = ''
|
||||||
|
@@ -755,6 +755,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 */
|
||||||
|
/**/
|
||||||
|
3364,
|
||||||
/**/
|
/**/
|
||||||
3363,
|
3363,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -8041,6 +8041,8 @@ compile_for(char_u *arg_start, cctx_T *cctx)
|
|||||||
}
|
}
|
||||||
arg_end = arg;
|
arg_end = arg;
|
||||||
|
|
||||||
|
if (cctx->ctx_skip != SKIP_YES)
|
||||||
|
{
|
||||||
// If we know the type of "var" and it is a not a supported type we can
|
// If we know the type of "var" and it is a not a supported type we can
|
||||||
// give an error now.
|
// give an error now.
|
||||||
vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
||||||
@@ -8187,6 +8189,7 @@ compile_for(char_u *arg_start, cctx_T *cctx)
|
|||||||
generate_instr_debug(cctx);
|
generate_instr_debug(cctx);
|
||||||
cctx->ctx_prev_lnum = save_prev_lnum;
|
cctx->ctx_prev_lnum = save_prev_lnum;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return arg_end;
|
return arg_end;
|
||||||
|
|
||||||
@@ -8217,6 +8220,8 @@ compile_endfor(char_u *arg, cctx_T *cctx)
|
|||||||
}
|
}
|
||||||
forscope = &scope->se_u.se_for;
|
forscope = &scope->se_u.se_for;
|
||||||
cctx->ctx_scope = scope->se_outer;
|
cctx->ctx_scope = scope->se_outer;
|
||||||
|
if (cctx->ctx_skip != SKIP_YES)
|
||||||
|
{
|
||||||
unwind_locals(cctx, scope->se_local_count);
|
unwind_locals(cctx, scope->se_local_count);
|
||||||
|
|
||||||
// At end of ":for" scope jump back to the FOR instruction.
|
// At end of ":for" scope jump back to the FOR instruction.
|
||||||
@@ -8232,6 +8237,7 @@ compile_endfor(char_u *arg, cctx_T *cctx)
|
|||||||
// Below the ":for" scope drop the "expr" list from the stack.
|
// Below the ":for" scope drop the "expr" list from the stack.
|
||||||
if (generate_instr_drop(cctx, ISN_DROP, 1) == NULL)
|
if (generate_instr_drop(cctx, ISN_DROP, 1) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
vim_free(scope);
|
vim_free(scope);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user