Fix all optimization-inhibiting integer-to-pointer casts

Following from PR #2481, we replace all integer-to-pointer casts [which
hide pointer provenance information (and thus inhibit
optimizations)](https://clang.llvm.org/extra/clang-tidy/checks/performance/no-int-to-ptr.html)
with equivalent operations that preserve this information. I have
enabled the corresponding clang-tidy check in our static analysis CI so
that we do not get bitten by this again in the future.
This commit is contained in:
Kevin Svetlitski 2023-07-24 10:33:36 -07:00 committed by Qi Wang
parent 4827bb17bd
commit 3e82f357bb
27 changed files with 116 additions and 66 deletions

View file

@ -236,7 +236,7 @@ arena_slab_reg_alloc(edata_t *slab, const bin_info_t *bin_info) {
assert(!bitmap_full(slab_data->bitmap, &bin_info->bitmap_info));
regind = bitmap_sfu(slab_data->bitmap, &bin_info->bitmap_info);
ret = (void *)((uintptr_t)edata_addr_get(slab) +
ret = (void *)((byte_t *)edata_addr_get(slab) +
(uintptr_t)(bin_info->reg_size * regind));
edata_nfree_dec(slab);
return ret;
@ -280,6 +280,7 @@ arena_slab_reg_alloc_batch(edata_t *slab, const bin_info_t *bin_info,
while (pop--) {
size_t bit = cfs_lu(&g);
size_t regind = shift + bit;
/* NOLINTNEXTLINE(performance-no-int-to-ptr) */
*(ptrs + i) = (void *)(base + regsize * regind);
i++;

View file

@ -368,6 +368,7 @@ check_background_thread_creation(tsd_t *tsd,
pre_reentrancy(tsd, NULL);
int err = background_thread_create_signals_masked(&info->thread,
/* NOLINTNEXTLINE(performance-no-int-to-ptr) */
NULL, background_thread_entry, (void *)(uintptr_t)i);
post_reentrancy(tsd);
@ -540,6 +541,7 @@ background_thread_create_locked(tsd_t *tsd, unsigned arena_ind) {
* background threads with the underlying pthread_create.
*/
int err = background_thread_create_signals_masked(&info->thread, NULL,
/* NOLINTNEXTLINE(performance-no-int-to-ptr) */
background_thread_entry, (void *)thread_ind);
post_reentrancy(tsd);

View file

@ -181,9 +181,9 @@ base_extent_bump_alloc_helper(edata_t *edata, size_t *gap_size, size_t size,
*gap_size = ALIGNMENT_CEILING((uintptr_t)edata_addr_get(edata),
alignment) - (uintptr_t)edata_addr_get(edata);
ret = (void *)((uintptr_t)edata_addr_get(edata) + *gap_size);
ret = (void *)((byte_t *)edata_addr_get(edata) + *gap_size);
assert(edata_bsize_get(edata) >= *gap_size + size);
edata_binit(edata, (void *)((uintptr_t)edata_addr_get(edata) +
edata_binit(edata, (void *)((byte_t *)edata_addr_get(edata) +
*gap_size + size), edata_bsize_get(edata) - *gap_size - size,
edata_sn_get(edata));
return ret;
@ -291,7 +291,7 @@ base_block_alloc(tsdn_t *tsdn, base_t *base, ehooks_t *ehooks, unsigned ind,
block->next = NULL;
assert(block_size >= header_size);
base_edata_init(extent_sn_next, &block->edata,
(void *)((uintptr_t)block + header_size), block_size - header_size);
(void *)((byte_t *)block + header_size), block_size - header_size);
return block;
}

View file

@ -50,7 +50,7 @@ cache_bin_preincrement(cache_bin_info_t *infos, szind_t ninfos, void *alloc,
assert(((uintptr_t)alloc & (computed_alignment - 1)) == 0);
}
*(uintptr_t *)((uintptr_t)alloc + *cur_offset) =
*(uintptr_t *)((byte_t *)alloc + *cur_offset) =
cache_bin_preceding_junk;
*cur_offset += sizeof(void *);
}
@ -58,7 +58,7 @@ cache_bin_preincrement(cache_bin_info_t *infos, szind_t ninfos, void *alloc,
void
cache_bin_postincrement(cache_bin_info_t *infos, szind_t ninfos, void *alloc,
size_t *cur_offset) {
*(uintptr_t *)((uintptr_t)alloc + *cur_offset) =
*(uintptr_t *)((byte_t *)alloc + *cur_offset) =
cache_bin_trailing_junk;
*cur_offset += sizeof(void *);
}
@ -71,12 +71,12 @@ cache_bin_init(cache_bin_t *bin, cache_bin_info_t *info, void *alloc,
* will access the slots toward higher addresses (for the benefit of
* adjacent prefetch).
*/
void *stack_cur = (void *)((uintptr_t)alloc + *cur_offset);
void *stack_cur = (void *)((byte_t *)alloc + *cur_offset);
void *full_position = stack_cur;
uint16_t bin_stack_size = info->ncached_max * sizeof(void *);
*cur_offset += bin_stack_size;
void *empty_position = (void *)((uintptr_t)alloc + *cur_offset);
void *empty_position = (void *)((byte_t *)alloc + *cur_offset);
/* Init to the empty position. */
bin->stack_head = (void **)empty_position;

View file

@ -100,7 +100,7 @@ ehooks_default_destroy(extent_hooks_t *extent_hooks, void *addr, size_t size,
bool
ehooks_default_commit_impl(void *addr, size_t offset, size_t length) {
return pages_commit((void *)((uintptr_t)addr + (uintptr_t)offset),
return pages_commit((void *)((byte_t *)addr + (uintptr_t)offset),
length);
}
@ -112,7 +112,7 @@ ehooks_default_commit(extent_hooks_t *extent_hooks, void *addr, size_t size,
bool
ehooks_default_decommit_impl(void *addr, size_t offset, size_t length) {
return pages_decommit((void *)((uintptr_t)addr + (uintptr_t)offset),
return pages_decommit((void *)((byte_t *)addr + (uintptr_t)offset),
length);
}
@ -125,7 +125,7 @@ ehooks_default_decommit(extent_hooks_t *extent_hooks, void *addr, size_t size,
#ifdef PAGES_CAN_PURGE_LAZY
bool
ehooks_default_purge_lazy_impl(void *addr, size_t offset, size_t length) {
return pages_purge_lazy((void *)((uintptr_t)addr + (uintptr_t)offset),
return pages_purge_lazy((void *)((byte_t *)addr + (uintptr_t)offset),
length);
}
@ -143,7 +143,7 @@ ehooks_default_purge_lazy(extent_hooks_t *extent_hooks, void *addr, size_t size,
#ifdef PAGES_CAN_PURGE_FORCED
bool
ehooks_default_purge_forced_impl(void *addr, size_t offset, size_t length) {
return pages_purge_forced((void *)((uintptr_t)addr +
return pages_purge_forced((void *)((byte_t *)addr +
(uintptr_t)offset), length);
}

View file

@ -743,7 +743,7 @@ extent_grow_retained(tsdn_t *tsdn, pac_t *pac, ehooks_t *ehooks,
/* A successful commit should return zeroed memory. */
if (config_debug) {
void *addr = edata_addr_get(edata);
size_t *p = (size_t *)(uintptr_t)addr;
size_t *p = (size_t *)addr;
/* Check the first page only. */
for (size_t i = 0; i < PAGE / sizeof(size_t); i++) {
assert(p[i] == 0);
@ -1199,7 +1199,7 @@ extent_split_impl(tsdn_t *tsdn, pac_t *pac, ehooks_t *ehooks,
}
edata_init(trail, edata_arena_ind_get(edata),
(void *)((uintptr_t)edata_base_get(edata) + size_a), size_b,
(void *)((byte_t *)edata_base_get(edata) + size_a), size_b,
/* slab */ false, SC_NSIZES, edata_sn_get(edata),
edata_state_get(edata), edata_zeroed_get(edata),
edata_committed_get(edata), EXTENT_PAI_PAC, EXTENT_NOT_HEAD);

View file

@ -8,6 +8,7 @@
/******************************************************************************/
/* Data. */
/* NOLINTNEXTLINE(performance-no-int-to-ptr) */
#define SBRK_INVALID ((void *)-1)
const char *opt_dss = DSS_DEFAULT;
@ -149,10 +150,10 @@ extent_alloc_dss(tsdn_t *tsdn, arena_t *arena, void *new_addr, size_t size,
* necessary to satisfy alignment. This space can be
* recycled for later use.
*/
void *gap_addr_page = (void *)(PAGE_CEILING(
(uintptr_t)max_cur));
void *ret = (void *)ALIGNMENT_CEILING(
(uintptr_t)gap_addr_page, alignment);
void *gap_addr_page = ALIGNMENT_ADDR2CEILING(max_cur,
PAGE);
void *ret = ALIGNMENT_ADDR2CEILING(
gap_addr_page, alignment);
size_t gap_size_page = (uintptr_t)ret -
(uintptr_t)gap_addr_page;
if (gap_size_page != 0) {
@ -167,7 +168,7 @@ extent_alloc_dss(tsdn_t *tsdn, arena_t *arena, void *new_addr, size_t size,
* Compute the address just past the end of the desired
* allocation space.
*/
void *dss_next = (void *)((uintptr_t)ret + size);
void *dss_next = (void *)((byte_t *)ret + size);
if ((uintptr_t)ret < (uintptr_t)max_cur ||
(uintptr_t)dss_next < (uintptr_t)max_cur) {
goto label_oom; /* Wrap-around. */

View file

@ -130,7 +130,7 @@ hpdata_reserve_alloc(hpdata_t *hpdata, size_t sz) {
hpdata_assert_consistent(hpdata);
return (void *)(
(uintptr_t)hpdata_addr_get(hpdata) + (result << LG_PAGE));
(byte_t *)hpdata_addr_get(hpdata) + (result << LG_PAGE));
}
void
@ -277,7 +277,7 @@ hpdata_purge_next(hpdata_t *hpdata, hpdata_purge_state_t *purge_state,
}
*r_purge_addr = (void *)(
(uintptr_t)hpdata_addr_get(hpdata) + purge_begin * PAGE);
(byte_t *)hpdata_addr_get(hpdata) + purge_begin * PAGE);
*r_purge_size = purge_len * PAGE;
purge_state->next_purge_search_begin = purge_begin + purge_len;

View file

@ -3446,7 +3446,7 @@ do_rallocx(void *ptr, size_t size, int flags, bool is_realloc) {
if (config_fill && unlikely(opt_junk_alloc) && usize > old_usize
&& !zero) {
size_t excess_len = usize - old_usize;
void *excess_start = (void *)((uintptr_t)p + old_usize);
void *excess_start = (void *)((byte_t *)p + old_usize);
junk_alloc_callback(excess_start, excess_len);
}
@ -3716,7 +3716,7 @@ je_xallocx(void *ptr, size_t size, size_t extra, int flags) {
if (config_fill && unlikely(opt_junk_alloc) && usize > old_usize &&
!zero) {
size_t excess_len = usize - old_usize;
void *excess_start = (void *)((uintptr_t)ptr + old_usize);
void *excess_start = (void *)((byte_t *)ptr + old_usize);
junk_alloc_callback(excess_start, excess_len);
}
label_not_resized:

View file

@ -113,10 +113,10 @@ large_ralloc_no_move_expand(tsdn_t *tsdn, edata_t *edata, size_t usize,
* of CACHELINE in [0 .. PAGE).
*/
void *zbase = (void *)
((uintptr_t)edata_addr_get(edata) + old_usize);
void *zpast = PAGE_ADDR2BASE((void *)((uintptr_t)zbase +
((byte_t *)edata_addr_get(edata) + old_usize);
void *zpast = PAGE_ADDR2BASE((void *)((byte_t *)zbase +
PAGE));
size_t nzero = (uintptr_t)zpast - (uintptr_t)zbase;
size_t nzero = (byte_t *)zpast - (byte_t *)zbase;
assert(nzero > 0);
memset(zbase, 0, nzero);
}

View file

@ -197,7 +197,7 @@ os_pages_map(void *addr, size_t size, size_t alignment, bool *commit) {
static void *
os_pages_trim(void *addr, size_t alloc_size, size_t leadsize, size_t size,
bool *commit) {
void *ret = (void *)((uintptr_t)addr + leadsize);
void *ret = (void *)((byte_t *)addr + leadsize);
assert(alloc_size >= leadsize + size);
#ifdef _WIN32
@ -217,7 +217,7 @@ os_pages_trim(void *addr, size_t alloc_size, size_t leadsize, size_t size,
os_pages_unmap(addr, leadsize);
}
if (trailsize != 0) {
os_pages_unmap((void *)((uintptr_t)ret + size), trailsize);
os_pages_unmap((void *)((byte_t *)ret + size), trailsize);
}
return ret;
#endif

View file

@ -85,8 +85,10 @@ prof_tctx_comp(const prof_tctx_t *a, const prof_tctx_t *b) {
return ret;
}
/* NOLINTBEGIN(performance-no-int-to-ptr) */
rb_gen(static UNUSED, tctx_tree_, prof_tctx_tree_t, prof_tctx_t,
tctx_link, prof_tctx_comp)
/* NOLINTEND(performance-no-int-to-ptr) */
static int
prof_gctx_comp(const prof_gctx_t *a, const prof_gctx_t *b) {
@ -100,8 +102,10 @@ prof_gctx_comp(const prof_gctx_t *a, const prof_gctx_t *b) {
return ret;
}
/* NOLINTBEGIN(performance-no-int-to-ptr) */
rb_gen(static UNUSED, gctx_tree_, prof_gctx_tree_t, prof_gctx_t, dump_link,
prof_gctx_comp)
/* NOLINTEND(performance-no-int-to-ptr) */
static int
prof_tdata_comp(const prof_tdata_t *a, const prof_tdata_t *b) {
@ -119,8 +123,10 @@ prof_tdata_comp(const prof_tdata_t *a, const prof_tdata_t *b) {
return ret;
}
/* NOLINTBEGIN(performance-no-int-to-ptr) */
rb_gen(static UNUSED, tdata_tree_, prof_tdata_tree_t, prof_tdata_t, tdata_link,
prof_tdata_comp)
/* NOLINTEND(performance-no-int-to-ptr) */
/******************************************************************************/
@ -1141,7 +1147,7 @@ prof_tdata_init_impl(tsd_t *tsd, uint64_t thr_uid, uint64_t thr_discrim,
return NULL;
}
tdata->vec = (void **)((uintptr_t)tdata + tdata_sz);
tdata->vec = (void **)((byte_t *)tdata + tdata_sz);
tdata->lock = prof_tdata_mutex_choose(thr_uid);
tdata->thr_uid = thr_uid;
tdata->thr_discrim = thr_discrim;

View file

@ -20,43 +20,43 @@ ssize_t opt_lg_san_uaf_align = SAN_LG_UAF_ALIGN_DEFAULT;
uintptr_t san_cache_bin_nonfast_mask = SAN_CACHE_BIN_NONFAST_MASK_DEFAULT;
static inline void
san_find_guarded_addr(edata_t *edata, uintptr_t *guard1, uintptr_t *guard2,
uintptr_t *addr, size_t size, bool left, bool right) {
san_find_guarded_addr(edata_t *edata, void **guard1, void **guard2,
void **addr, size_t size, bool left, bool right) {
assert(!edata_guarded_get(edata));
assert(size % PAGE == 0);
*addr = (uintptr_t)edata_base_get(edata);
*addr = edata_base_get(edata);
if (left) {
*guard1 = *addr;
*addr += SAN_PAGE_GUARD;
*addr = ((byte_t *)*addr) + SAN_PAGE_GUARD;
} else {
*guard1 = 0;
*guard1 = NULL;
}
if (right) {
*guard2 = *addr + size;
*guard2 = ((byte_t *)*addr) + size;
} else {
*guard2 = 0;
*guard2 = NULL;
}
}
static inline void
san_find_unguarded_addr(edata_t *edata, uintptr_t *guard1, uintptr_t *guard2,
uintptr_t *addr, size_t size, bool left, bool right) {
san_find_unguarded_addr(edata_t *edata, void **guard1, void **guard2,
void **addr, size_t size, bool left, bool right) {
assert(edata_guarded_get(edata));
assert(size % PAGE == 0);
*addr = (uintptr_t)edata_base_get(edata);
*addr = edata_base_get(edata);
if (right) {
*guard2 = *addr + size;
*guard2 = ((byte_t *)*addr) + size;
} else {
*guard2 = 0;
*guard2 = NULL;
}
if (left) {
*guard1 = *addr - SAN_PAGE_GUARD;
assert(*guard1 != 0);
*guard1 = ((byte_t *)*addr) - SAN_PAGE_GUARD;
assert(*guard1 != NULL);
*addr = *guard1;
} else {
*guard1 = 0;
*guard1 = NULL;
}
}
@ -73,16 +73,16 @@ san_guard_pages(tsdn_t *tsdn, ehooks_t *ehooks, edata_t *edata, emap_t *emap,
? san_two_side_unguarded_sz(size_with_guards)
: san_one_side_unguarded_sz(size_with_guards);
uintptr_t guard1, guard2, addr;
void *guard1, *guard2, *addr;
san_find_guarded_addr(edata, &guard1, &guard2, &addr, usize, left,
right);
assert(edata_state_get(edata) == extent_state_active);
ehooks_guard(tsdn, ehooks, (void *)guard1, (void *)guard2);
ehooks_guard(tsdn, ehooks, guard1, guard2);
/* Update the guarded addr and usable size of the edata. */
edata_size_set(edata, usize);
edata_addr_set(edata, (void *)addr);
edata_addr_set(edata, addr);
edata_guarded_set(edata, true);
if (remap) {
@ -108,7 +108,7 @@ san_unguard_pages_impl(tsdn_t *tsdn, ehooks_t *ehooks, edata_t *edata,
? san_two_side_guarded_sz(size)
: san_one_side_guarded_sz(size);
uintptr_t guard1, guard2, addr;
void *guard1, *guard2, *addr;
san_find_unguarded_addr(edata, &guard1, &guard2, &addr, size, left,
right);

View file

@ -768,9 +768,9 @@ tcache_create_explicit(tsd_t *tsd) {
if (mem == NULL) {
return NULL;
}
tcache_t *tcache = (void *)((uintptr_t)mem + tcache_bin_alloc_size);
tcache_t *tcache = (void *)((byte_t *)mem + tcache_bin_alloc_size);
tcache_slow_t *tcache_slow =
(void *)((uintptr_t)mem + tcache_bin_alloc_size + sizeof(tcache_t));
(void *)((byte_t *)mem + tcache_bin_alloc_size + sizeof(tcache_t));
tcache_init(tsd, tcache_slow, tcache, mem);
tcache_arena_associate(tsd_tsdn(tsd), tcache_slow, tcache,