src: introduce upx::ptr_reinterpret_cast

This commit is contained in:
Markus F.X.J. Oberhumer 2023-10-29 16:52:24 +01:00
parent cd1df6f6b1
commit 38a676f6f7
5 changed files with 42 additions and 4 deletions

View File

@ -88,6 +88,26 @@ ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_le("abc", "abz"))
// util
**************************************************************************/
TEST_CASE("ptr_reinterpret_cast") {
using upx::ptr_reinterpret_cast;
byte *an = nullptr;
int *in = nullptr;
CHECK((an == ptr_reinterpret_cast<byte *>(an)));
CHECK((an == ptr_reinterpret_cast<byte *>(in)));
CHECK((in == ptr_reinterpret_cast<int *>(an)));
CHECK((in == ptr_reinterpret_cast<int *>(in)));
const byte *ac = nullptr;
const int *ic = nullptr;
CHECK((ac == ptr_reinterpret_cast<byte *>(an)));
CHECK((ac == ptr_reinterpret_cast<const byte *>(ac)));
CHECK((ac == ptr_reinterpret_cast<byte *>(in)));
CHECK((ac == ptr_reinterpret_cast<const byte *>(ic)));
CHECK((ic == ptr_reinterpret_cast<int *>(an)));
CHECK((ic == ptr_reinterpret_cast<const int *>(ac)));
CHECK((ic == ptr_reinterpret_cast<int *>(in)));
CHECK((ic == ptr_reinterpret_cast<const int *>(ic)));
}
TEST_CASE("noncopyable") {
struct Test : private upx::noncopyable {
int v = 1;

View File

@ -31,6 +31,24 @@
namespace upx {
/*************************************************************************
// misc
**************************************************************************/
// a reinterpret_cast that does not trigger -Wcast-align warnings
template <class Result, class From>
forceinline Result ptr_reinterpret_cast(From *ptr) {
static_assert(std::is_pointer_v<Result>);
static_assert(!std::is_const_v<std::remove_pointer_t<Result> >); // enforce same constness
return (Result) (void *) ptr;
}
template <class Result, class From>
forceinline Result ptr_reinterpret_cast(const From *ptr) {
static_assert(std::is_pointer_v<Result>);
static_assert(std::is_const_v<std::remove_pointer_t<Result> >); // required
return (Result) (const void *) ptr;
}
/*************************************************************************
// type_traits
**************************************************************************/

View File

@ -158,7 +158,7 @@ inline R *xspan_make_helper__(R * /*dummy*/, MemBuffer &mb) noexcept {
#define XSPAN_S_VAR(type, var, first, ...) type *var = XSPAN_S_MAKE(type, (first))
// cast to a different type (creates a new value)
#define XSPAN_TYPE_CAST(type, x) (reinterpret_cast<type *>(x))
#define XSPAN_TYPE_CAST(type, x) (upx::ptr_reinterpret_cast<type *>(x))
// poison a pointer: point to a non-null invalid address
#define XSPAN_INVALIDATE(x) ptr_invalidate_and_poison(x)

View File

@ -284,8 +284,8 @@ public:
inline CSelf<U> type_cast() const {
typedef CSelf<U> R;
typedef typename R::pointer rpointer;
return R(R::Unchecked, reinterpret_cast<rpointer>(ptr), size_in_bytes,
reinterpret_cast<rpointer>(base));
return R(R::Unchecked, upx::ptr_reinterpret_cast<rpointer>(ptr), size_in_bytes,
upx::ptr_reinterpret_cast<rpointer>(base));
}
bool operator==(pointer other) const noexcept { return ptr == other; }

View File

@ -127,7 +127,7 @@ public:
inline CSelf<U> type_cast() const {
typedef CSelf<U> R;
typedef typename R::pointer rpointer;
return R(reinterpret_cast<rpointer>(ptr));
return R(upx::ptr_reinterpret_cast<rpointer>(ptr));
}
// comparison