mirror of
https://github.com/neovim/neovim.git
synced 2025-09-19 09:48:19 +00:00
api helpers: Save/restore more values in try_enter/try_leave
This fixes memory leak reported by ASAN. This also somehow fixes test40, though I have no idea why except that that test yields memory leak report.
This commit is contained in:
@@ -49,13 +49,17 @@ void try_enter(TryState *const tstate)
|
|||||||
.trylevel = trylevel,
|
.trylevel = trylevel,
|
||||||
.got_int = got_int,
|
.got_int = got_int,
|
||||||
.did_throw = did_throw,
|
.did_throw = did_throw,
|
||||||
|
.need_rethrow = need_rethrow,
|
||||||
|
.current_exception = current_exception,
|
||||||
.msg_list = (const struct msglist *const *)msg_list,
|
.msg_list = (const struct msglist *const *)msg_list,
|
||||||
.private_msg_list = NULL,
|
.private_msg_list = NULL,
|
||||||
};
|
};
|
||||||
trylevel = 1;
|
trylevel = 1;
|
||||||
got_int = false;
|
got_int = false;
|
||||||
did_throw = false;
|
did_throw = false;
|
||||||
|
need_rethrow = false;
|
||||||
msg_list = &tstate->private_msg_list;
|
msg_list = &tstate->private_msg_list;
|
||||||
|
current_exception = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// End try block, set the error message if any and restore previous state
|
/// End try block, set the error message if any and restore previous state
|
||||||
@@ -72,14 +76,17 @@ bool try_leave(const TryState *const tstate, Error *const err)
|
|||||||
{
|
{
|
||||||
const bool ret = !try_end(err);
|
const bool ret = !try_end(err);
|
||||||
assert(trylevel == 0);
|
assert(trylevel == 0);
|
||||||
|
assert(!need_rethrow);
|
||||||
assert(!got_int);
|
assert(!got_int);
|
||||||
assert(!did_throw);
|
assert(!did_throw);
|
||||||
assert(msg_list == &tstate->private_msg_list);
|
assert(msg_list == &tstate->private_msg_list);
|
||||||
assert(*msg_list == NULL);
|
assert(*msg_list == NULL);
|
||||||
|
assert(current_exception == NULL);
|
||||||
trylevel = tstate->trylevel;
|
trylevel = tstate->trylevel;
|
||||||
got_int = tstate->got_int;
|
got_int = tstate->got_int;
|
||||||
did_throw = tstate->did_throw;
|
did_throw = tstate->did_throw;
|
||||||
msg_list = (struct msglist **)tstate->msg_list;
|
msg_list = (struct msglist **)tstate->msg_list;
|
||||||
|
current_exception = tstate->current_exception;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,6 +103,8 @@ void try_start(void)
|
|||||||
/// @return true if an error occurred
|
/// @return true if an error occurred
|
||||||
bool try_end(Error *err)
|
bool try_end(Error *err)
|
||||||
{
|
{
|
||||||
|
// Note: all globals manipulated here should be saved/restored in
|
||||||
|
// try_enter/try_leave.
|
||||||
--trylevel;
|
--trylevel;
|
||||||
|
|
||||||
// Without this it stops processing all subsequent VimL commands and
|
// Without this it stops processing all subsequent VimL commands and
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
#include "nvim/api/private/defs.h"
|
#include "nvim/api/private/defs.h"
|
||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
#include "nvim/memory.h"
|
#include "nvim/memory.h"
|
||||||
|
#include "nvim/ex_eval.h"
|
||||||
#include "nvim/lib/kvec.h"
|
#include "nvim/lib/kvec.h"
|
||||||
|
|
||||||
#define OBJECT_OBJ(o) o
|
#define OBJECT_OBJ(o) o
|
||||||
@@ -90,6 +91,8 @@ typedef struct {
|
|||||||
int trylevel;
|
int trylevel;
|
||||||
int got_int;
|
int got_int;
|
||||||
int did_throw;
|
int did_throw;
|
||||||
|
int need_rethrow;
|
||||||
|
except_T *current_exception;
|
||||||
struct msglist *private_msg_list;
|
struct msglist *private_msg_list;
|
||||||
const struct msglist *const *msg_list;
|
const struct msglist *const *msg_list;
|
||||||
} TryState;
|
} TryState;
|
||||||
|
@@ -565,6 +565,8 @@ static void discard_exception(except_T *excp, int was_finished)
|
|||||||
void discard_current_exception(void)
|
void discard_current_exception(void)
|
||||||
{
|
{
|
||||||
discard_exception(current_exception, FALSE);
|
discard_exception(current_exception, FALSE);
|
||||||
|
// Note: all globals manipulated here should be saved/restored in
|
||||||
|
// try_enter/try_leave.
|
||||||
current_exception = NULL;
|
current_exception = NULL;
|
||||||
did_throw = FALSE;
|
did_throw = FALSE;
|
||||||
need_rethrow = FALSE;
|
need_rethrow = FALSE;
|
||||||
|
@@ -2341,8 +2341,6 @@ static bool color_cmdline(void)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int saved_force_abort = force_abort;
|
|
||||||
force_abort = true;
|
|
||||||
bool arg_allocated = false;
|
bool arg_allocated = false;
|
||||||
typval_T arg = {
|
typval_T arg = {
|
||||||
.v_type = VAR_STRING,
|
.v_type = VAR_STRING,
|
||||||
@@ -2504,7 +2502,6 @@ color_cmdline_end:
|
|||||||
if (can_free_cb) {
|
if (can_free_cb) {
|
||||||
callback_free(&color_cb);
|
callback_free(&color_cb);
|
||||||
}
|
}
|
||||||
force_abort = saved_force_abort;
|
|
||||||
if (arg_allocated) {
|
if (arg_allocated) {
|
||||||
tv_clear(&arg);
|
tv_clear(&arg);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user