Patch 8.2.4103
Problem:    Vim9: variable declared in for loop not initialzed.
Solution:   Always initialze the variable. (closes #9535)
Files:      src/vim9instr.c, src/proto/vim9instr.pro, src/vim9compile.c,
            src/testdir/test_vim9_assign.vim


*** ../vim-8.2.4102/src/vim9instr.c     2022-01-13 21:15:17.237958552 +0000
--- src/vim9instr.c     2022-01-15 21:27:51.386880879 +0000
***************
*** 1845,1850 ****
--- 1845,1869 ----
      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
  generate_store_lhs(cctx_T *cctx, lhs_T *lhs, int instr_count, int is_decl)
  {
***************
*** 1869,1876 ****
            varnumber_T val = isn->isn_arg.number;
            garray_T    *stack = &cctx->ctx_type_stack;
  
!           if (val == 0 && is_decl)
            {
                --instr->ga_len;
            }
            else
--- 1888,1896 ----
            varnumber_T val = isn->isn_arg.number;
            garray_T    *stack = &cctx->ctx_type_stack;
  
!           if (val == 0 && is_decl && !inside_loop_scope(cctx))
            {
+               // zero is the default value, no need to do anything
                --instr->ga_len;
            }
            else
*** ../vim-8.2.4102/src/proto/vim9instr.pro     2022-01-08 18:43:36.877446896 
+0000
--- src/proto/vim9instr.pro     2022-01-15 21:28:22.982855994 +0000
***************
*** 63,68 ****
--- 63,69 ----
  int generate_cmdmods(cctx_T *cctx, cmdmod_T *cmod);
  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 inside_loop_scope(cctx_T *cctx);
  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 delete_instr(isn_T *isn);
*** ../vim-8.2.4102/src/vim9compile.c   2022-01-15 14:16:33.938539800 +0000
--- src/vim9compile.c   2022-01-15 21:33:22.102611149 +0000
***************
*** 2256,2267 ****
                    case VAR_VOID:
                    case VAR_INSTR:
                    case VAR_SPECIAL:  // cannot happen
!                       // This is skipped for local variables, they are
!                       // always initialized to zero.
!                       if (lhs.lhs_dest == dest_local)
                            skip_store = TRUE;
                        else
                            generate_PUSHNR(cctx, 0);
                        break;
                }
            }
--- 2256,2272 ----
                    case VAR_VOID:
                    case VAR_INSTR:
                    case VAR_SPECIAL:  // cannot happen
!                       // This is skipped for local variables, they are always
!                       // initialized to zero.  But in a "for" or "while" loop
!                       // the value may have been changed.
!                       if (lhs.lhs_dest == dest_local
!                                                  && !inside_loop_scope(cctx))
                            skip_store = TRUE;
                        else
+                       {
+                           instr_count = instr->ga_len;
                            generate_PUSHNR(cctx, 0);
+                       }
                        break;
                }
            }
*** ../vim-8.2.4102/src/testdir/test_vim9_assign.vim    2022-01-06 
21:10:24.469027861 +0000
--- src/testdir/test_vim9_assign.vim    2022-01-15 21:36:49.642356047 +0000
***************
*** 587,592 ****
--- 587,627 ----
    CheckDefFailure(lines, 'E1012: Type mismatch; expected list<number> but got 
dict<unknown>', 2)
  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()
    var lines =<< trim END
        var l1: list<number>
*** ../vim-8.2.4102/src/version.c       2022-01-15 21:08:11.899395839 +0000
--- src/version.c       2022-01-15 21:28:14.490862718 +0000
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     4103,
  /**/

-- 
"A mouse can be just as dangerous as a bullet or a bomb."
             (US Representative Lamar Smith, R-Texas)

 /// Bram Moolenaar -- b...@moolenaar.net -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220115214519.522C71C03C8%40moolenaar.net.

Raspunde prin e-mail lui