mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06: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; \
|
*top++ = (b)->root; \
|
||||||
while (top != stack) { \
|
while (top != stack) { \
|
||||||
x = *--top; \
|
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) \
|
for (i = 0; i <= x->n; ++i) \
|
||||||
if (__KB_PTR(b, x)[i]) { \
|
if (__KB_PTR(b, x)[i]) { \
|
||||||
if (top - stack == (int)max) { \
|
if (top - stack == (int)max) { \
|
||||||
@ -82,10 +82,10 @@
|
|||||||
} \
|
} \
|
||||||
*top++ = __KB_PTR(b, x)[i]; \
|
*top++ = __KB_PTR(b, x)[i]; \
|
||||||
} \
|
} \
|
||||||
xfree(x); \
|
XFREE_CLEAR(x); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
xfree(stack); \
|
XFREE_CLEAR(stack); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \
|
#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_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*)); \
|
memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, x)[i + 2], (unsigned int)(x->n - i - 1) * sizeof(void*)); \
|
||||||
--x->n; \
|
--x->n; \
|
||||||
xfree(z); \
|
XFREE_CLEAR(z); \
|
||||||
return __kb_delp_aux_##name(b, y, k, s); \
|
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_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*)); \
|
memmove(&__KB_PTR(b, x)[i], &__KB_PTR(b, x)[i + 1], (unsigned int)(x->n - i) * sizeof(void*)); \
|
||||||
--x->n; \
|
--x->n; \
|
||||||
xfree(xp); \
|
XFREE_CLEAR(xp); \
|
||||||
xp = y; \
|
xp = y; \
|
||||||
} else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n == T - 1) { \
|
} 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]; \
|
__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_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*)); \
|
memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, x)[i + 2], (unsigned int)(x->n - i - 1) * sizeof(void*)); \
|
||||||
--x->n; \
|
--x->n; \
|
||||||
xfree(y); \
|
XFREE_CLEAR(y); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
return __kb_delp_aux_##name(b, xp, k, s); \
|
return __kb_delp_aux_##name(b, xp, k, s); \
|
||||||
@ -306,7 +306,7 @@
|
|||||||
--b->n_nodes; \
|
--b->n_nodes; \
|
||||||
x = b->root; \
|
x = b->root; \
|
||||||
b->root = __KB_PTR(b, x)[0]; \
|
b->root = __KB_PTR(b, x)[0]; \
|
||||||
xfree(x); \
|
XFREE_CLEAR(x); \
|
||||||
} \
|
} \
|
||||||
return ret; \
|
return ret; \
|
||||||
} \
|
} \
|
||||||
|
@ -181,7 +181,7 @@ typedef khint_t khiter_t;
|
|||||||
#define krealloc(P,Z) xrealloc(P,Z)
|
#define krealloc(P,Z) xrealloc(P,Z)
|
||||||
#endif
|
#endif
|
||||||
#ifndef kfree
|
#ifndef kfree
|
||||||
#define kfree(P) xfree(P)
|
#define kfree(P) XFREE_CLEAR(P)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define __ac_HASH_UPPER 0.77
|
#define __ac_HASH_UPPER 0.77
|
||||||
|
@ -46,9 +46,9 @@
|
|||||||
static inline void kmp_destroy_##name(kmp_##name##_t *mp) { \
|
static inline void kmp_destroy_##name(kmp_##name##_t *mp) { \
|
||||||
size_t k; \
|
size_t k; \
|
||||||
for (k = 0; k < mp->n; 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) { \
|
static inline kmptype_t *kmp_alloc_##name(kmp_##name##_t *mp) { \
|
||||||
mp->cnt++; \
|
mp->cnt++; \
|
||||||
@ -100,7 +100,7 @@
|
|||||||
} \
|
} \
|
||||||
kmp_free(name, kl->mp, p); \
|
kmp_free(name, kl->mp, p); \
|
||||||
kmp_destroy(name, kl->mp); \
|
kmp_destroy(name, kl->mp); \
|
||||||
xfree(kl); \
|
XFREE_CLEAR(kl); \
|
||||||
} \
|
} \
|
||||||
static inline void kl_push_##name(kl_##name##_t *kl, kltype_t d) { \
|
static inline void kl_push_##name(kl_##name##_t *kl, kltype_t d) { \
|
||||||
kl1_##name *q, *p = kmp_alloc(name, kl->mp); \
|
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_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_A(v, i) ((v).items[(i)])
|
||||||
#define kv_pop(v) ((v).items[--(v).size])
|
#define kv_pop(v) ((v).items[--(v).size])
|
||||||
#define kv_size(v) ((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
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_ALWAYS_INLINE
|
||||||
{
|
{
|
||||||
memcpy(dest, src, size);
|
memcpy(dest, src, size);
|
||||||
xfree(src);
|
XFREE_CLEAR(src);
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,7 +201,7 @@ static inline void *_memcpy_free(void *const restrict dest,
|
|||||||
#define kvi_destroy(v) \
|
#define kvi_destroy(v) \
|
||||||
do { \
|
do { \
|
||||||
if ((v).items != (v).init_array) { \
|
if ((v).items != (v).init_array) { \
|
||||||
xfree((v).items); \
|
XFREE_CLEAR((v).items); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -136,14 +136,14 @@ static inline void funcprefix##_rb_free(TypeName##RingBuffer *const rb) \
|
|||||||
RINGBUF_FORALL(rb, RBType, rbitem) { \
|
RINGBUF_FORALL(rb, RBType, rbitem) { \
|
||||||
rbfree(rbitem); \
|
rbfree(rbitem); \
|
||||||
} \
|
} \
|
||||||
xfree(rb->buf); \
|
XFREE_CLEAR(rb->buf); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline void funcprefix##_rb_dealloc(TypeName##RingBuffer *const rb) \
|
static inline void funcprefix##_rb_dealloc(TypeName##RingBuffer *const rb) \
|
||||||
REAL_FATTR_UNUSED; \
|
REAL_FATTR_UNUSED; \
|
||||||
static inline void funcprefix##_rb_dealloc(TypeName##RingBuffer *const rb) \
|
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, \
|
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
|
/// free() wrapper that delegates to the backing memory manager
|
||||||
|
///
|
||||||
|
/// @note Use XFREE_CLEAR() instead, if possible.
|
||||||
void xfree(void *ptr)
|
void xfree(void *ptr)
|
||||||
{
|
{
|
||||||
free(ptr);
|
free(ptr);
|
||||||
|
@ -40,4 +40,15 @@ extern bool entered_free_all_mem;
|
|||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "memory.h.generated.h"
|
# include "memory.h.generated.h"
|
||||||
#endif
|
#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
|
#endif // NVIM_MEMORY_H
|
||||||
|
@ -148,10 +148,10 @@ describe('autocmd', function()
|
|||||||
funcs.execute('autocmd Tabnew'))
|
funcs.execute('autocmd Tabnew'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('window works', function()
|
it('internal `aucmd_win` window', function()
|
||||||
-- Nvim uses a special window to execute certain actions for an invisible buffer,
|
-- Nvim uses a special internal window `aucmd_win` to execute certain
|
||||||
-- internally called autcmd_win and mentioned in the docs at :help E813
|
-- actions for an invisible buffer (:help E813).
|
||||||
-- Do some safety checks for redrawing and api accesses to this window.
|
-- Check redrawing and API accesses to this window.
|
||||||
|
|
||||||
local screen = Screen.new(50, 10)
|
local screen = Screen.new(50, 10)
|
||||||
screen:attach()
|
screen:attach()
|
||||||
|
Loading…
Reference in New Issue
Block a user