mem/metaslab: use uintptr_t alignment functions
It is UB to offset from `nullptr` (except perhaps with a 0 offset). Apparently clang is able to use this to reason, given `void* p`, that comparing `__builtin_align_down(p, x)` against `handle.fake_large_remote` (i.e., a `static inline constexpr` `nullptr`) must be the same as comparing `p` itself against `nullptr`. In `MetaEntry`'s constructor, converting the provided `RemoteAllocator*` to `uintptr_t` before offsetting avoids the UB. (While here, don't use `address_cast()`, as `address_t` will, on CHERI, be `ptraddr_t` and not `uintptr_t`.) Doing the alignment in `get_remote` at `uintptr_t` before casting to `RemoteAllocator*`, rather than converting and then aligning, prevents the reasoning above from eliminating the alignment.
This commit is contained in:
committed by
Matthew Parkinson
parent
3e70963772
commit
2ba0de76b3
@@ -180,8 +180,9 @@ namespace snmalloc
|
||||
MetaEntry(Metaslab* meta, RemoteAllocator* remote, sizeclass_t sizeclass)
|
||||
: meta(meta)
|
||||
{
|
||||
/* remote might be nullptr; cast to uintptr_t before offsetting */
|
||||
remote_and_sizeclass =
|
||||
address_cast(pointer_offset<char>(remote, sizeclass));
|
||||
pointer_offset(reinterpret_cast<uintptr_t>(remote), sizeclass);
|
||||
}
|
||||
|
||||
[[nodiscard]] Metaslab* get_metaslab() const
|
||||
@@ -192,7 +193,7 @@ namespace snmalloc
|
||||
[[nodiscard]] RemoteAllocator* get_remote() const
|
||||
{
|
||||
return reinterpret_cast<RemoteAllocator*>(
|
||||
bits::align_down(remote_and_sizeclass, alignof(RemoteAllocator)));
|
||||
pointer_align_down<alignof(RemoteAllocator)>(remote_and_sizeclass));
|
||||
}
|
||||
|
||||
[[nodiscard]] sizeclass_t get_sizeclass() const
|
||||
|
||||
Reference in New Issue
Block a user