diff src/vim9compile.c @ 23291:8e1427ac2bce v8.2.2191

patch 8.2.2191: Vim9: using wrong name with lambda in nested function Commit: https://github.com/vim/vim/commit/58a52f215a568b32c8a3aec0ccdb383f1a76dba0 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Dec 22 18:56:55 2020 +0100 patch 8.2.2191: Vim9: using wrong name with lambda in nested function Problem: Vim9: using wrong name with lambda in nested function. Solution: Copy the lambda name earlier. (closes https://github.com/vim/vim/issues/7525)
author Bram Moolenaar <Bram@vim.org>
date Tue, 22 Dec 2020 19:00:06 +0100
parents ac701146c708
children 7951c5098e8e
line wrap: on
line diff
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1428,20 +1428,27 @@ generate_FUNCREF(cctx_T *cctx, ufunc_T *
 
 /*
  * Generate an ISN_NEWFUNC instruction.
+ * "lambda_name" and "func_name" must be in allocated memory and will be
+ * consumed.
  */
     static int
 generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name)
 {
     isn_T	*isn;
-    char_u	*name;
-
-    RETURN_OK_IF_SKIP(cctx);
-    name = vim_strsave(lambda_name);
-    if (name == NULL)
+
+    if (cctx->ctx_skip == SKIP_YES)
+    {
+	vim_free(lambda_name);
+	vim_free(func_name);
+	return OK;
+    }
+    if ((isn = generate_instr(cctx, ISN_NEWFUNC)) == NULL)
+    {
+	vim_free(lambda_name);
+	vim_free(func_name);
 	return FAIL;
-    if ((isn = generate_instr(cctx, ISN_NEWFUNC)) == NULL)
-	return FAIL;
-    isn->isn_arg.newfunc.nf_lambda = name;
+    }
+    isn->isn_arg.newfunc.nf_lambda = lambda_name;
     isn->isn_arg.newfunc.nf_global = func_name;
 
     return OK;
@@ -4840,7 +4847,7 @@ compile_nested_function(exarg_T *eap, cc
     char_u	*name_end = to_name_end(eap->arg, TRUE);
     char_u	*lambda_name;
     ufunc_T	*ufunc;
-    int		r;
+    int		r = FAIL;
 
     if (eap->forceit)
     {
@@ -4883,16 +4890,21 @@ compile_nested_function(exarg_T *eap, cc
     eap->cookie = cctx;
     eap->skip = cctx->ctx_skip == SKIP_YES;
     eap->forceit = FALSE;
-    lambda_name = get_lambda_name();
+    lambda_name = vim_strsave(get_lambda_name());
+    if (lambda_name == NULL)
+	return NULL;
     ufunc = define_function(eap, lambda_name);
 
     if (ufunc == NULL)
-	return eap->skip ? (char_u *)"" : NULL;
+    {
+	r = eap->skip ? OK : FAIL;
+	goto theend;
+    }
     if (ufunc->uf_def_status == UF_TO_BE_COMPILED
 	    && compile_def_function(ufunc, TRUE, cctx) == FAIL)
     {
 	func_ptr_unref(ufunc);
-	return NULL;
+	goto theend;
     }
 
     if (is_global)
@@ -4903,7 +4915,10 @@ compile_nested_function(exarg_T *eap, cc
 	if (func_name == NULL)
 	    r = FAIL;
 	else
+	{
 	    r = generate_NEWFUNC(cctx, lambda_name, func_name);
+	    lambda_name = NULL;
+	}
     }
     else
     {
@@ -4913,9 +4928,9 @@ compile_nested_function(exarg_T *eap, cc
 	int block_depth = cctx->ctx_ufunc->uf_block_depth;
 
 	if (lvar == NULL)
-	    return NULL;
+	    goto theend;
 	if (generate_FUNCREF(cctx, ufunc) == FAIL)
-	    return NULL;
+	    goto theend;
 	r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL);
 
 	// copy over the block scope IDs
@@ -4930,8 +4945,11 @@ compile_nested_function(exarg_T *eap, cc
 	    }
 	}
     }
-
     // TODO: warning for trailing text?
+    r = OK;
+
+theend:
+    vim_free(lambda_name);
     return r == FAIL ? NULL : (char_u *)"";
 }