all: cleanups
This commit is contained in:
@@ -62,7 +62,7 @@ static noinline void init_use_simple_mcheck() noexcept {
|
||||
static bool use_simple_mcheck() noexcept {
|
||||
static upx_std_once_flag init_done;
|
||||
upx_std_call_once(init_done, init_use_simple_mcheck);
|
||||
// NOTE: clang-analyzer-unix.Malloc does not know that this flag is "constant"
|
||||
// NOTE: clang-analyzer-unix.Malloc does not know that this flag is "constant"; see below
|
||||
return use_simple_mcheck_flag;
|
||||
}
|
||||
#else
|
||||
@@ -176,9 +176,10 @@ void MemBuffer::fill(unsigned off, unsigned len, int value) {
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#define PTR_BITS(p) ((unsigned) ((upx_uintptr_t) (p) &0xffffffff))
|
||||
#define MAGIC1(p) ((PTR_BITS(p) ^ 0xfefdbeeb) | 1)
|
||||
#define MAGIC2(p) ((PTR_BITS(p) ^ 0xfefdbeeb ^ 0x80024011) | 1)
|
||||
// for use_simple_mcheck()
|
||||
#define PTR_BITS32(p) ((unsigned) ((upx_uintptr_t) (p) &0xffffffff))
|
||||
#define MAGIC1(p) ((PTR_BITS32(p) ^ 0xfefdbeeb) | 1)
|
||||
#define MAGIC2(p) ((PTR_BITS32(p) ^ 0xfefdbeeb ^ 0x88224411) | 1)
|
||||
|
||||
void MemBuffer::checkState() const {
|
||||
if (!ptr)
|
||||
@@ -215,7 +216,7 @@ void MemBuffer::alloc(upx_uint64_t bytes) {
|
||||
// store magic constants to detect buffer overruns
|
||||
set_ne32(p - 8, size_in_bytes);
|
||||
set_ne32(p - 4, MAGIC1(p));
|
||||
set_ne32(p + size_in_bytes, MAGIC2(p));
|
||||
set_ne32(p + size_in_bytes + 0, MAGIC2(p));
|
||||
set_ne32(p + size_in_bytes + 4, stats.global_alloc_counter);
|
||||
}
|
||||
ptr = (pointer) (void *) p;
|
||||
|
||||
@@ -787,6 +787,7 @@ TEST_CASE("get_ratio") {
|
||||
CHECK(get_ratio(2 * UPX_RSIZE_MAX, 1024ull * UPX_RSIZE_MAX) == 9999999);
|
||||
}
|
||||
|
||||
namespace {
|
||||
template <class T>
|
||||
struct TestTriBool {
|
||||
static void test(bool expect_true, int x) noexcept {
|
||||
@@ -831,9 +832,14 @@ struct TestTriBool {
|
||||
CHECK(a.isOther());
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("TriBool") {
|
||||
static_assert(!tribool(false));
|
||||
static_assert(tribool(true));
|
||||
static_assert(!tribool(tribool::Other));
|
||||
TestTriBool<tribool>::test(false, -1);
|
||||
//
|
||||
TestTriBool<TriBool<upx_int8_t> >::test(false, -1);
|
||||
TestTriBool<TriBool<upx_int64_t> >::test(false, -1);
|
||||
//
|
||||
|
||||
+11
-11
@@ -209,24 +209,24 @@ public:
|
||||
static_assert(TOther != 0 && TOther != 1);
|
||||
enum value_type : underlying_type { False = 0, True = 1, Other = TOther };
|
||||
// constructors
|
||||
forceinline TriBool() noexcept = default;
|
||||
forceinline constexpr TriBool() noexcept = default;
|
||||
forceinline ~TriBool() noexcept = default;
|
||||
constexpr TriBool(value_type x) noexcept : value(x) {}
|
||||
constexpr TriBool(promoted_type x) noexcept : value(x == 0 ? False : (x == 1 ? True : Other)) {}
|
||||
// access
|
||||
value_type getValue() const noexcept { return value; }
|
||||
constexpr value_type getValue() const noexcept { return value; }
|
||||
// checks for > 0, so TOther determines if Other is false (the default) or true
|
||||
explicit operator bool() const noexcept { return value > False; }
|
||||
explicit constexpr operator bool() const noexcept { return value > False; }
|
||||
// query; this is NOT the same as operator bool()
|
||||
bool isStrictFalse() const noexcept { return value == False; }
|
||||
bool isStrictTrue() const noexcept { return value == True; }
|
||||
bool isStrictBool() const noexcept { return value == False || value == True; }
|
||||
bool isOther() const noexcept { return value != False && value != True; }
|
||||
constexpr bool isStrictFalse() const noexcept { return value == False; }
|
||||
constexpr bool isStrictTrue() const noexcept { return value == True; }
|
||||
constexpr bool isStrictBool() const noexcept { return value == False || value == True; }
|
||||
constexpr bool isOther() const noexcept { return value != False && value != True; }
|
||||
// "other" can mean many things, depending on usage context, so provide some alternative names:
|
||||
// forceinline bool isDefault() const noexcept { return isOther(); } // might be misleading
|
||||
forceinline bool isIndeterminate() const noexcept { return isOther(); }
|
||||
forceinline bool isUndecided() const noexcept { return isOther(); }
|
||||
// forceinline bool isUnset() const noexcept { return isOther(); } // might be misleading
|
||||
// constexpr bool isDefault() const noexcept { return isOther(); } // might be misleading
|
||||
constexpr bool isIndeterminate() const noexcept { return isOther(); }
|
||||
constexpr bool isUndecided() const noexcept { return isOther(); }
|
||||
// constexpr bool isUnset() const noexcept { return isOther(); } // might be misleading
|
||||
constexpr bool operator==(TriBool other) const noexcept { return value == other.value; }
|
||||
constexpr bool operator==(value_type other) const noexcept { return value == other; }
|
||||
constexpr bool operator==(promoted_type other) const noexcept { return value == other; }
|
||||
|
||||
+2
-1
@@ -33,7 +33,7 @@ XSPAN_NAMESPACE_BEGIN
|
||||
// debugging stats
|
||||
struct XSpanStats {
|
||||
upx_std_atomic(size_t) check_range_counter;
|
||||
// these normally will be zero, but doctest checks will populate them
|
||||
// these usually will be zero, but internal doctest checks will populate them; see dt_xspan.cpp
|
||||
upx_std_atomic(size_t) fail_nullptr;
|
||||
upx_std_atomic(size_t) fail_nullbase;
|
||||
upx_std_atomic(size_t) fail_not_same_base;
|
||||
@@ -71,6 +71,7 @@ void xspan_fail_range_range() {
|
||||
}
|
||||
|
||||
void xspan_check_range(const void *ptr, const void *base, ptrdiff_t size_in_bytes) {
|
||||
// info: pointers are out of range deliberatly during internal doctest checks; see dt_xspan.cpp
|
||||
xspan_stats.check_range_counter += 1;
|
||||
if very_unlikely (ptr == nullptr)
|
||||
xspan_fail_range_nullptr();
|
||||
|
||||
Reference in New Issue
Block a user