mirror of
https://github.com/neovim/neovim.git
synced 2024-12-29 14:41:06 -07:00
refactor: introduce XFREE_CLEAR()
Unfortunately we cannot indiscriminately replace xfree() with XFREE_CLEAR(), because comparing pointers after freeing them is a common pattern. Example in `tv_list_remove_items()`: xfree(li); if (li == item2) { break; } Instead we can do it selectively/explicitly. ref #1375
This commit is contained in:
parent
4769deb36a
commit
a9d7ec4587
@ -72,7 +72,7 @@
|
||||
*top++ = (b)->root; \
|
||||
while (top != stack) { \
|
||||
x = *--top; \
|
||||
if (x->is_internal == 0) { xfree(x); continue; } \
|
||||
if (x->is_internal == 0) { XFREE_CLEAR(x); continue; } \
|
||||
for (i = 0; i <= x->n; ++i) \
|
||||
if (__KB_PTR(b, x)[i]) { \
|
||||
if (top - stack == (int)max) { \
|
||||
@ -82,10 +82,10 @@
|
||||
} \
|
||||
*top++ = __KB_PTR(b, x)[i]; \
|
||||
} \
|
||||
xfree(x); \
|
||||
XFREE_CLEAR(x); \
|
||||
} \
|
||||
} \
|
||||
xfree(stack); \
|
||||
XFREE_CLEAR(stack); \
|
||||
} while (0)
|
||||
|
||||
#define __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \
|
||||
@ -253,7 +253,7 @@
|
||||
memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
|
||||
memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, x)[i + 2], (unsigned int)(x->n - i - 1) * sizeof(void*)); \
|
||||
--x->n; \
|
||||
xfree(z); \
|
||||
XFREE_CLEAR(z); \
|
||||
return __kb_delp_aux_##name(b, y, k, s); \
|
||||
} \
|
||||
} \
|
||||
@ -281,7 +281,7 @@
|
||||
memmove(&__KB_KEY(key_t, x)[i - 1], &__KB_KEY(key_t, x)[i], (unsigned int)(x->n - i) * sizeof(key_t)); \
|
||||
memmove(&__KB_PTR(b, x)[i], &__KB_PTR(b, x)[i + 1], (unsigned int)(x->n - i) * sizeof(void*)); \
|
||||
--x->n; \
|
||||
xfree(xp); \
|
||||
XFREE_CLEAR(xp); \
|
||||
xp = y; \
|
||||
} else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n == T - 1) { \
|
||||
__KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \
|
||||
@ -291,7 +291,7 @@
|
||||
memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
|
||||
memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, x)[i + 2], (unsigned int)(x->n - i - 1) * sizeof(void*)); \
|
||||
--x->n; \
|
||||
xfree(y); \
|
||||
XFREE_CLEAR(y); \
|
||||
} \
|
||||
} \
|
||||
return __kb_delp_aux_##name(b, xp, k, s); \
|
||||
@ -306,7 +306,7 @@
|
||||
--b->n_nodes; \
|
||||
x = b->root; \
|
||||
b->root = __KB_PTR(b, x)[0]; \
|
||||
xfree(x); \
|
||||
XFREE_CLEAR(x); \
|
||||
} \
|
||||
return ret; \
|
||||
} \
|
||||
|
@ -181,7 +181,7 @@ typedef khint_t khiter_t;
|
||||
#define krealloc(P,Z) xrealloc(P,Z)
|
||||
#endif
|
||||
#ifndef kfree
|
||||
#define kfree(P) xfree(P)
|
||||
#define kfree(P) XFREE_CLEAR(P)
|
||||
#endif
|
||||
|
||||
#define __ac_HASH_UPPER 0.77
|
||||
|
@ -46,9 +46,9 @@
|
||||
static inline void kmp_destroy_##name(kmp_##name##_t *mp) { \
|
||||
size_t k; \
|
||||
for (k = 0; k < mp->n; k++) { \
|
||||
kmpfree_f(mp->buf[k]); xfree(mp->buf[k]); \
|
||||
kmpfree_f(mp->buf[k]); XFREE_CLEAR(mp->buf[k]); \
|
||||
} \
|
||||
xfree(mp->buf); xfree(mp); \
|
||||
XFREE_CLEAR(mp->buf); XFREE_CLEAR(mp); \
|
||||
} \
|
||||
static inline kmptype_t *kmp_alloc_##name(kmp_##name##_t *mp) { \
|
||||
mp->cnt++; \
|
||||
@ -100,7 +100,7 @@
|
||||
} \
|
||||
kmp_free(name, kl->mp, p); \
|
||||
kmp_destroy(name, kl->mp); \
|
||||
xfree(kl); \
|
||||
XFREE_CLEAR(kl); \
|
||||
} \
|
||||
static inline void kl_push_##name(kl_##name##_t *kl, kltype_t d) { \
|
||||
kl1_##name *q, *p = kmp_alloc(name, kl->mp); \
|
||||
|
@ -58,7 +58,7 @@
|
||||
}
|
||||
|
||||
#define kv_init(v) ((v).size = (v).capacity = 0, (v).items = 0)
|
||||
#define kv_destroy(v) xfree((v).items)
|
||||
#define kv_destroy(v) XFREE_CLEAR((v).items)
|
||||
#define kv_A(v, i) ((v).items[(i)])
|
||||
#define kv_pop(v) ((v).items[--(v).size])
|
||||
#define kv_size(v) ((v).size)
|
||||
@ -138,7 +138,7 @@ static inline void *_memcpy_free(void *const restrict dest,
|
||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_ALWAYS_INLINE
|
||||
{
|
||||
memcpy(dest, src, size);
|
||||
xfree(src);
|
||||
XFREE_CLEAR(src);
|
||||
return dest;
|
||||
}
|
||||
|
||||
@ -201,7 +201,7 @@ static inline void *_memcpy_free(void *const restrict dest,
|
||||
#define kvi_destroy(v) \
|
||||
do { \
|
||||
if ((v).items != (v).init_array) { \
|
||||
xfree((v).items); \
|
||||
XFREE_CLEAR((v).items); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
@ -136,14 +136,14 @@ static inline void funcprefix##_rb_free(TypeName##RingBuffer *const rb) \
|
||||
RINGBUF_FORALL(rb, RBType, rbitem) { \
|
||||
rbfree(rbitem); \
|
||||
} \
|
||||
xfree(rb->buf); \
|
||||
XFREE_CLEAR(rb->buf); \
|
||||
} \
|
||||
\
|
||||
static inline void funcprefix##_rb_dealloc(TypeName##RingBuffer *const rb) \
|
||||
REAL_FATTR_UNUSED; \
|
||||
static inline void funcprefix##_rb_dealloc(TypeName##RingBuffer *const rb) \
|
||||
{ \
|
||||
xfree(rb->buf); \
|
||||
XFREE_CLEAR(rb->buf); \
|
||||
} \
|
||||
\
|
||||
static inline void funcprefix##_rb_push(TypeName##RingBuffer *const rb, \
|
||||
|
@ -110,6 +110,8 @@ void *xmalloc(size_t size)
|
||||
}
|
||||
|
||||
/// free() wrapper that delegates to the backing memory manager
|
||||
///
|
||||
/// @note Use XFREE_CLEAR() instead, if possible.
|
||||
void xfree(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
|
@ -40,4 +40,15 @@ extern bool entered_free_all_mem;
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "memory.h.generated.h"
|
||||
#endif
|
||||
|
||||
#define XFREE_CLEAR(ptr) \
|
||||
do { \
|
||||
/* Take the address to avoid double evaluation. #1375 */ \
|
||||
void **ptr_ = (void **)&(ptr); \
|
||||
xfree(*ptr_); \
|
||||
/* coverity[dead-store] */ \
|
||||
*ptr_ = NULL; \
|
||||
(void)(*ptr_); \
|
||||
} while (0)
|
||||
|
||||
#endif // NVIM_MEMORY_H
|
||||
|
@ -148,10 +148,10 @@ describe('autocmd', function()
|
||||
funcs.execute('autocmd Tabnew'))
|
||||
end)
|
||||
|
||||
it('window works', function()
|
||||
-- Nvim uses a special window to execute certain actions for an invisible buffer,
|
||||
-- internally called autcmd_win and mentioned in the docs at :help E813
|
||||
-- Do some safety checks for redrawing and api accesses to this window.
|
||||
it('internal `aucmd_win` window', function()
|
||||
-- Nvim uses a special internal window `aucmd_win` to execute certain
|
||||
-- actions for an invisible buffer (:help E813).
|
||||
-- Check redrawing and API accesses to this window.
|
||||
|
||||
local screen = Screen.new(50, 10)
|
||||
screen:attach()
|
||||
|
Loading…
Reference in New Issue
Block a user