all: cmake and noexcept updates

This commit is contained in:
Markus F.X.J. Oberhumer 2023-06-23 14:13:08 +02:00
parent 7fafc68940
commit 5d2c74008e
7 changed files with 71 additions and 36 deletions

View File

@ -3,7 +3,12 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer # Copyright (C) Markus Franz Xaver Johannes Oberhumer
# #
cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR) # CMake >= 3.20 is recommended # CMake version check; using a somewhat current CMake version is highly recommended
if(NOT DEFINED UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION)
cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR) # needed for CXX_STANDARD 17
else()
cmake_minimum_required(VERSION "${UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION}" FATAL_ERROR)
endif()
# Build requirements: # Build requirements:
# A C++ compiler that fully implements C++17: clang-5, gcc-8 or msvc-2019 16.11 # A C++ compiler that fully implements C++17: clang-5, gcc-8 or msvc-2019 16.11
# (older or other compilers may work but are unsupported, use at your own risk) # (older or other compilers may work but are unsupported, use at your own risk)
@ -129,25 +134,33 @@ if(NOT UPX_CONFIG_DISABLE_BZIP2)
file(GLOB bzip2_SOURCES "vendor/bzip2/*.c") file(GLOB bzip2_SOURCES "vendor/bzip2/*.c")
list(SORT bzip2_SOURCES) list(SORT bzip2_SOURCES)
add_library(upx_vendor_bzip2 STATIC ${bzip2_SOURCES}) add_library(upx_vendor_bzip2 STATIC ${bzip2_SOURCES})
set_property(TARGET upx_vendor_bzip2 PROPERTY C_STANDARD 11) if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
set_property(TARGET upx_vendor_bzip2 PROPERTY C_STANDARD 11)
endif() endif()
endif() # UPX_CONFIG_DISABLE_BZIP2
file(GLOB ucl_SOURCES "vendor/ucl/src/*.c") file(GLOB ucl_SOURCES "vendor/ucl/src/*.c")
list(SORT ucl_SOURCES) list(SORT ucl_SOURCES)
add_library(upx_vendor_ucl STATIC ${ucl_SOURCES}) add_library(upx_vendor_ucl STATIC ${ucl_SOURCES})
set_property(TARGET upx_vendor_ucl PROPERTY C_STANDARD 11) if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
set_property(TARGET upx_vendor_ucl PROPERTY C_STANDARD 11)
endif()
file(GLOB zlib_SOURCES "vendor/zlib/*.c") file(GLOB zlib_SOURCES "vendor/zlib/*.c")
list(SORT zlib_SOURCES) list(SORT zlib_SOURCES)
add_library(upx_vendor_zlib STATIC ${zlib_SOURCES}) add_library(upx_vendor_zlib STATIC ${zlib_SOURCES})
set_property(TARGET upx_vendor_zlib PROPERTY C_STANDARD 11) if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
set_property(TARGET upx_vendor_zlib PROPERTY C_STANDARD 11)
endif()
if(NOT UPX_CONFIG_DISABLE_ZSTD) if(NOT UPX_CONFIG_DISABLE_ZSTD)
file(GLOB zstd_SOURCES "vendor/zstd/lib/*/*.c") file(GLOB zstd_SOURCES "vendor/zstd/lib/*/*.c")
list(SORT zstd_SOURCES) list(SORT zstd_SOURCES)
add_library(upx_vendor_zstd STATIC ${zstd_SOURCES}) add_library(upx_vendor_zstd STATIC ${zstd_SOURCES})
set_property(TARGET upx_vendor_zstd PROPERTY C_STANDARD 11) if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
set_property(TARGET upx_vendor_zstd PROPERTY C_STANDARD 11)
endif() endif()
endif() # UPX_CONFIG_DISABLE_ZSTD
file(GLOB upx_SOURCES "src/*.cpp" "src/[cfu]*/*.cpp") file(GLOB upx_SOURCES "src/*.cpp" "src/[cfu]*/*.cpp")
list(SORT upx_SOURCES) list(SORT upx_SOURCES)

View File

@ -322,7 +322,7 @@ struct TestBELE {
template <class A, class B> template <class A, class B>
struct TestNoAliasingStruct { struct TestNoAliasingStruct {
static noinline bool test(A *a, B *b) { static noinline bool test(A *a, B *b) noexcept {
*a = 0; *a = 0;
*b = 0; *b = 0;
*b -= 3; *b -= 3;
@ -330,13 +330,14 @@ struct TestNoAliasingStruct {
} }
}; };
template <class A, class B> template <class A, class B>
static forceinline bool testNoAliasing(A *a, B *b) { static forceinline bool testNoAliasing(A *a, B *b) noexcept {
return TestNoAliasingStruct<A, B>::test(a, b); return TestNoAliasingStruct<A, B>::test(a, b);
} }
template <class T> template <class T>
struct TestIntegerWrap { struct TestIntegerWrap {
static inline bool inc(T x) { return x + 1 > x; } static inline bool inc_gt(const T x) noexcept { return x + 1 > x; }
static inline bool dec(T x) { return x - 1 < x; } static inline bool dec_lt(const T x) noexcept { return x - 1 < x; }
static inline bool neg_eq(const T x) noexcept { return T(0) - x == x; }
}; };
} // namespace } // namespace
@ -504,21 +505,42 @@ void upx_compiler_sanity_check(void) {
assert(testNoAliasing(&u.v_int, &u.v_llong)); assert(testNoAliasing(&u.v_int, &u.v_llong));
assert(testNoAliasing(&u.v_long, &u.v_llong)); assert(testNoAliasing(&u.v_long, &u.v_llong));
assert(TestIntegerWrap<unsigned>::inc(0)); assert(TestIntegerWrap<unsigned>::inc_gt(0));
assert(!TestIntegerWrap<unsigned>::inc(UINT_MAX)); assert(!TestIntegerWrap<unsigned>::inc_gt(UINT_MAX));
assert(TestIntegerWrap<unsigned>::dec(1)); assert(TestIntegerWrap<unsigned>::dec_lt(1));
assert(!TestIntegerWrap<unsigned>::dec(0)); assert(!TestIntegerWrap<unsigned>::dec_lt(0));
assert(TestIntegerWrap<unsigned>::neg_eq(0));
assert(!TestIntegerWrap<unsigned>::neg_eq(1));
assert(!TestIntegerWrap<unsigned>::neg_eq(UINT_MAX));
// check working -fno-strict-overflow // check working -fno-strict-overflow
assert(TestIntegerWrap<int>::inc(0)); assert(TestIntegerWrap<int>::inc_gt(0));
assert(!TestIntegerWrap<int>::inc(INT_MAX)); assert(!TestIntegerWrap<int>::inc_gt(INT_MAX));
assert(TestIntegerWrap<int>::dec(0)); assert(TestIntegerWrap<int>::dec_lt(0));
assert(!TestIntegerWrap<int>::dec(INT_MIN)); assert(!TestIntegerWrap<int>::dec_lt(INT_MIN));
assert(TestIntegerWrap<int>::neg_eq(0));
assert(!TestIntegerWrap<int>::neg_eq(1));
assert(!TestIntegerWrap<int>::neg_eq(INT_MAX));
assert(TestIntegerWrap<int>::neg_eq(INT_MIN)); // !!
} }
/************************************************************************* /*************************************************************************
// some doctest test cases // some doctest test cases
**************************************************************************/ **************************************************************************/
TEST_CASE("noncopyable") {
struct Test : private noncopyable {
int v = 1;
};
Test t = {};
CHECK(t.v == 1);
#if (ACC_CC_MSC) // MSVC thinks that Test is not std::is_trivially_copyable; compiler bug?
t.v = 0;
#else
mem_clear(&t);
#endif
CHECK(t.v == 0);
}
TEST_CASE("acc_vget") { TEST_CASE("acc_vget") {
CHECK_EQ(acc_vget_int(0, 0), 0); CHECK_EQ(acc_vget_int(0, 0), 0);
CHECK_EQ(acc_vget_long(1, -1), 1); CHECK_EQ(acc_vget_long(1, -1), 1);

View File

@ -410,12 +410,12 @@ inline void mem_clear(T (&array)[N]) noexcept = delete;
class noncopyable { class noncopyable {
protected: protected:
inline noncopyable() noexcept {} inline noncopyable() noexcept {}
inline ~noncopyable() noexcept {} inline ~noncopyable() noexcept = default;
private: private:
noncopyable(const noncopyable &) DELETED_FUNCTION; // copy constructor noncopyable(const noncopyable &) noexcept DELETED_FUNCTION; // copy constructor
noncopyable& operator=(const noncopyable &) DELETED_FUNCTION; // copy assignment noncopyable& operator=(const noncopyable &) noexcept DELETED_FUNCTION; // copy assignment
noncopyable(noncopyable &&) DELETED_FUNCTION; // move constructor noncopyable(noncopyable &&) noexcept DELETED_FUNCTION; // move constructor
noncopyable& operator=(noncopyable &&) DELETED_FUNCTION; // move assignment noncopyable& operator=(noncopyable &&) noexcept DELETED_FUNCTION; // move assignment
}; };

View File

@ -148,7 +148,7 @@ bool Packer::testUnpackFormat(int format) const {
return canUnpackFormat(format); return canUnpackFormat(format);
} }
bool ph_skipVerify(const PackHeader &ph) { bool ph_skipVerify(const PackHeader &ph) noexcept {
if (M_IS_DEFLATE(ph.method)) if (M_IS_DEFLATE(ph.method))
return false; return false;
if (M_IS_LZMA(ph.method)) if (M_IS_LZMA(ph.method))
@ -158,17 +158,17 @@ bool ph_skipVerify(const PackHeader &ph) {
return true; return true;
} }
int force_method(int method) // mark as forced int force_method(int method) noexcept // mark as forced
{ {
return (0x80ul << 24) | method; return (0x80ul << 24) | method;
} }
int is_forced_method(int method) // predicate int is_forced_method(int method) noexcept // predicate
{ {
return -0x80 == (method >> 24); return -0x80 == (method >> 24);
} }
int forced_method(int method) // extract the forced method int forced_method(int method) noexcept // extract the forced method
{ {
if (is_forced_method(method)) if (is_forced_method(method))
method &= ~(0x80ul << 24); method &= ~(0x80ul << 24);

View File

@ -36,16 +36,15 @@ class UiPacker;
class Filter; class Filter;
/************************************************************************* /*************************************************************************
// // PackHeader
// also see stub/src/include/header.S
**************************************************************************/ **************************************************************************/
// see stub/src/include/header.S
class PackHeader final { class PackHeader final {
friend class Packer; friend class Packer;
// these are strictly private to friend Packer // these are strictly private to friend Packer
PackHeader(); PackHeader() noexcept;
void putPackHeader(SPAN_S(byte) p); void putPackHeader(SPAN_S(byte) p);
bool decodePackHeaderFromBuf(SPAN_S(const byte) b, int blen); bool decodePackHeaderFromBuf(SPAN_S(const byte) b, int blen);
@ -91,7 +90,7 @@ public:
unsigned overlap_overhead; unsigned overlap_overhead;
}; };
bool ph_skipVerify(const PackHeader &ph); bool ph_skipVerify(const PackHeader &ph) noexcept;
void ph_decompress(PackHeader &ph, SPAN_P(const byte) in, SPAN_P(byte) out, bool verify_checksum, void ph_decompress(PackHeader &ph, SPAN_P(const byte) in, SPAN_P(byte) out, bool verify_checksum,
Filter *ft); Filter *ft);
bool ph_testOverlappingDecompression(const PackHeader &ph, SPAN_P(const byte) buf, bool ph_testOverlappingDecompression(const PackHeader &ph, SPAN_P(const byte) buf,
@ -358,8 +357,8 @@ private:
Packer &operator=(Packer &&) = delete; Packer &operator=(Packer &&) = delete;
}; };
int force_method(int method); // (0x80ul<<24)|method int force_method(int method) noexcept; // (0x80ul<<24)|method
int forced_method(int method); // (0x80ul<<24)|method ==> method int forced_method(int method) noexcept; // (0x80ul<<24)|method ==> method
int is_forced_method(int method); // predicate int is_forced_method(int method) noexcept; // predicate
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */

View File

@ -35,7 +35,7 @@
// least to detect older versions, so this is a little bit messy. // least to detect older versions, so this is a little bit messy.
**************************************************************************/ **************************************************************************/
PackHeader::PackHeader() : version(-1), format(-1) {} PackHeader::PackHeader() noexcept : version(-1), format(-1) {}
/************************************************************************* /*************************************************************************
// very simple checksum for the header itself (since version 10) // very simple checksum for the header itself (since version 10)

View File

@ -31,6 +31,7 @@
// gets destructed when leaving scope or on exceptions. // gets destructed when leaving scope or on exceptions.
/************************************************************************* /*************************************************************************
// MemBufferBase
// provides some base functionality for treating a MemBuffer as a pointer // provides some base functionality for treating a MemBuffer as a pointer
**************************************************************************/ **************************************************************************/
@ -84,7 +85,7 @@ public: // raw access
private: private:
// disable taking the address => force passing by reference // disable taking the address => force passing by reference
// [I'm not too sure about this design decision, but we can always allow it if needed] // [I'm not too sure about this design decision, but we can always allow it if needed]
MemBufferBase<T> *operator&() const DELETED_FUNCTION; MemBufferBase<T> *operator&() const noexcept DELETED_FUNCTION;
}; };
/************************************************************************* /*************************************************************************