Fix the remaining clang-tidy warnings.
This introduces a new `address_t` type and two new casts: `pointer_cast` and `address_cast` for casting between an `address_t` and a pointer. These should make it easier to audit the codebase for casts between pointers and integers. In particular, the remaining `reinterpret_cast`s and `pointer_cast`s should be the only places where we could perform invalid pointer arithmetic. Also adds a `pointer_offset` helper that adds an offset (in bytes) to a pointer, preserving its original type. This is a sufficiently common pattern that it seemed worthwhile to centralise it.
This commit is contained in:
42
src/ds/address.h
Normal file
42
src/ds/address.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
namespace snmalloc
|
||||
{
|
||||
/**
|
||||
* The type used for an address. Currently, all addresses are assumed to be
|
||||
* provenance-carrying values and so it is possible to cast back from the
|
||||
* result of arithmetic on an address_t. Eventually, this will want to be
|
||||
* separated into two types, one for raw addresses and one for addresses that
|
||||
* can be cast back to pointers.
|
||||
*/
|
||||
typedef uintptr_t address_t;
|
||||
|
||||
/**
|
||||
* Perform pointer arithmetic and return the adjusted pointer.
|
||||
*/
|
||||
template<typename T>
|
||||
inline T* pointer_offset(T* base, size_t diff)
|
||||
{
|
||||
return reinterpret_cast<T*>(reinterpret_cast<char*>(base) + diff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast from a pointer type to an address.
|
||||
*/
|
||||
template<typename T>
|
||||
inline address_t address_cast(T* ptr)
|
||||
{
|
||||
return reinterpret_cast<address_t>(ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast from an address back to a pointer of the specified type. All uses of
|
||||
* this will eventually need auditing for CHERI compatibility.
|
||||
*/
|
||||
template<typename T>
|
||||
inline T* pointer_cast(address_t address)
|
||||
{
|
||||
return reinterpret_cast<T*>(address);
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,8 @@
|
||||
|
||||
// #define USE_LZCNT
|
||||
|
||||
#include "address.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
@@ -310,7 +312,7 @@ namespace snmalloc
|
||||
|
||||
inline static size_t hash(void* p)
|
||||
{
|
||||
size_t x = (size_t)p;
|
||||
size_t x = static_cast<size_t>(address_cast(p));
|
||||
|
||||
if (is64())
|
||||
{
|
||||
@@ -359,7 +361,8 @@ namespace snmalloc
|
||||
{
|
||||
assert(next_pow2(alignment) == alignment);
|
||||
|
||||
return (((size_t)p | size) & (alignment - 1)) == 0;
|
||||
return ((static_cast<size_t>(address_cast(p)) | size) &
|
||||
(alignment - 1)) == 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -371,8 +374,8 @@ namespace snmalloc
|
||||
using S = std::make_signed_t<T>;
|
||||
constexpr S shift = (sizeof(S) * 8) - 1;
|
||||
|
||||
S a = (S)(v + 1);
|
||||
S b = (S)(mod - a - 1);
|
||||
S a = static_cast<S>(v + 1);
|
||||
S b = static_cast<S>(mod - a - 1);
|
||||
return a & ~(b >> shift);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace snmalloc
|
||||
public:
|
||||
operator T()
|
||||
{
|
||||
return (T)(value & (length - 1));
|
||||
return static_cast<T>(value & (length - 1));
|
||||
}
|
||||
|
||||
T& operator=(const T v)
|
||||
|
||||
Reference in New Issue
Block a user