From eb021accd1df7887fba5950cab8ba95fdcb9d48b Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Mon, 25 Sep 2023 13:47:43 +0200 Subject: [PATCH] CI updates --- .github/workflows/ci.yml | 4 +- .github/workflows/weekly-ci-bs-by-hand.yml | 4 +- .../weekly-ci-bs-cmake-windows-make.yml | 5 +- .../weekly-ci-bs-cmake-windows-ninja.yml | 6 ++- .../workflows/weekly-ci-cc-alpine-linux.yml | 26 +++++------ .github/workflows/weekly-ci-cc-zigcc.yml | 4 +- .github/workflows/weekly-ci-rt-checkers.yml | 2 +- CMakeLists.txt | 6 ++- src/check/dt_cxxlib.cpp | 1 + src/except.cpp | 6 +-- src/file.cpp | 6 +-- src/ui.cpp | 6 +-- src/ui.h | 2 +- src/util/cxxlib.h | 46 +++++++++++-------- src/util/membuffer.cpp | 4 +- src/util/util.cpp | 19 ++++---- src/util/util.h | 4 +- 17 files changed, 86 insertions(+), 65 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3965c1d7..1d67d292 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,8 +12,8 @@ env: CMAKE_REQUIRED_QUIET: OFF DEBIAN_FRONTEND: noninteractive UPX_CMAKE_BUILD_FLAGS: --verbose - # 2023-09-19 - ZIG_DIST_VERSION: 0.12.0-dev.415+5af5d87ad + # 2023-09-25 + ZIG_DIST_VERSION: 0.12.0-dev.573+c9413a880 jobs: job-rebuild-and-verify-stubs: diff --git a/.github/workflows/weekly-ci-bs-by-hand.yml b/.github/workflows/weekly-ci-bs-by-hand.yml index 202af5e4..126a844c 100644 --- a/.github/workflows/weekly-ci-bs-by-hand.yml +++ b/.github/workflows/weekly-ci-bs-by-hand.yml @@ -30,8 +30,8 @@ jobs: echo "installing shells: $shells" apk update && apk upgrade && apk add ccache g++ git $shells # enable ccache and some warnings - warn="-Wall -Wextra -Werror" - echo -e "CC=ccache gcc $warn\nCXX=ccache g++ -std=gnu++17 $warn" >> $GITHUB_ENV + xflags="-static -Wall -Wextra -Werror" + echo -e "CC=ccache gcc $xflags\nCXX=ccache g++ -std=gnu++17 $xflags" >> $GITHUB_ENV # this seems to be needed when running in a container (beause of UID mismatch??) git config --global --add safe.directory '*' # create user upx:upx 2000:2000 for file system tests below ("sudo") diff --git a/.github/workflows/weekly-ci-bs-cmake-windows-make.yml b/.github/workflows/weekly-ci-bs-cmake-windows-make.yml index cb9ba6c2..30969de4 100644 --- a/.github/workflows/weekly-ci-bs-cmake-windows-make.yml +++ b/.github/workflows/weekly-ci-bs-cmake-windows-make.yml @@ -18,7 +18,8 @@ jobs: fail-fast: false matrix: include: -# INFO: the following don't work => use Ninja (weekly-ci-bs-cmake-windows-ninja.yml) instead +# INFO: the following don't work with GNU make (probably some quoting problems with spaces or backslashes) +# => use Ninja generator instead; see weekly-ci-bs-cmake-windows-ninja.yml # # cl (msvc) # - { os: windows-2019, cc: cl, cxx: cl, vsversion: 2019, arch: amd64 } # - { os: windows-2019, cc: cl, cxx: cl, vsversion: 2019, arch: amd64_arm64 } @@ -28,6 +29,8 @@ jobs: # - { os: windows-2022, cc: cl, cxx: cl, vsversion: 2022, arch: amd64_x86 } # # clang-cl # - { os: windows-2022, cc: clang-cl, cxx: clang-cl, vsversion: 2022, arch: amd64 } + # clang + - { os: windows-2022, cc: clang, cxx: 'clang++', arch: amd64, xflags: '-static' } # gcc (mingw-gcc) - { os: windows-2022, cc: gcc, cxx: 'g++', arch: amd64, xflags: '-static' } env: diff --git a/.github/workflows/weekly-ci-bs-cmake-windows-ninja.yml b/.github/workflows/weekly-ci-bs-cmake-windows-ninja.yml index 956a0a8e..f9afb241 100644 --- a/.github/workflows/weekly-ci-bs-cmake-windows-ninja.yml +++ b/.github/workflows/weekly-ci-bs-cmake-windows-ninja.yml @@ -18,7 +18,7 @@ jobs: fail-fast: false matrix: include: -# # cl (msvc) + # cl (msvc) - { os: windows-2019, cc: cl, cxx: cl, vsversion: 2019, arch: amd64 } - { os: windows-2019, cc: cl, cxx: cl, vsversion: 2019, arch: amd64_arm64 } - { os: windows-2019, cc: cl, cxx: cl, vsversion: 2019, arch: amd64_x86 } @@ -27,6 +27,8 @@ jobs: - { os: windows-2022, cc: cl, cxx: cl, vsversion: 2022, arch: amd64_x86 } # clang-cl - { os: windows-2022, cc: clang-cl, cxx: clang-cl, vsversion: 2022, arch: amd64 } + # clang + - { os: windows-2022, cc: clang, cxx: 'clang++', arch: amd64, xflags: '-static' } # gcc (mingw-gcc) - { os: windows-2022, cc: gcc, cxx: 'g++', arch: amd64, xflags: '-static' } env: @@ -48,7 +50,7 @@ jobs: shell: bash run: | command -v ninja >/dev/null || choco install -y --no-progress ninja - xtarget="windows-make-${{ matrix.cc }}-${{ matrix.vsversion }}-${{ matrix.arch}}" + xtarget="windows-ninja-${{ matrix.cc }}-${{ matrix.vsversion }}-${{ matrix.arch}}" echo "xtarget=$xtarget" >> $GITHUB_ENV - name: 'Build cmake Ninja Debug' shell: bash diff --git a/.github/workflows/weekly-ci-cc-alpine-linux.yml b/.github/workflows/weekly-ci-cc-alpine-linux.yml index eadaa85e..87add69e 100644 --- a/.github/workflows/weekly-ci-cc-alpine-linux.yml +++ b/.github/workflows/weekly-ci-cc-alpine-linux.yml @@ -81,66 +81,66 @@ jobs: if: matrix.use_cxx20 run: | export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON - make -C "upx with space" UPX_XTARGET=clang-cxx20-static CC="clang -std=gnu17 -static" CXX="clang++ -std=gnu++20 -static" + make -C "upx with space" UPX_XTARGET=clang-static-cxx20 CC="clang -static -std=gnu17" CXX="clang++ -static -std=gnu++20" - name: ${{ format('Build clang C++20 Debug with {0}', env.clang_package) }} if: matrix.use_cxx20 run: | export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON - make -C "upx with space" UPX_XTARGET=clang-cxx20-static CC="clang -std=gnu17 -static" CXX="clang++ -std=gnu++20 -static" xtarget/debug + make -C "upx with space" UPX_XTARGET=clang-static-cxx20 CC="clang -static -std=gnu17" CXX="clang++ -static -std=gnu++20" xtarget/debug - name: ${{ format('Build gcc C++20 Release with {0}', env.gcc_package) }} if: matrix.use_cxx20 run: | export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON - make -C "upx with space" UPX_XTARGET=gcc-cxx20-static CC="gcc -std=gnu17 -static" CXX="g++ -std=gnu++20 -static" + make -C "upx with space" UPX_XTARGET=gcc-static-cxx20 CC="gcc -static -std=gnu17" CXX="g++ -static -std=gnu++20" - name: ${{ format('Build gcc C++20 Debug with {0}', env.gcc_package) }} if: matrix.use_cxx20 run: | export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON - make -C "upx with space" UPX_XTARGET=gcc-cxx20-static CC="gcc -std=gnu17 -static" CXX="g++ -std=gnu++20 -static" xtarget/debug + make -C "upx with space" UPX_XTARGET=gcc-static-cxx20 CC="gcc -static -std=gnu17" CXX="g++ -static -std=gnu++20" xtarget/debug - # build with C23 and C++23 (using -std=gnu++2b) + # build with C23 and C++23 - name: ${{ format('Build clang C++23 Release with {0}', env.clang_package) }} if: matrix.use_cxx23 || matrix.use_cxx2b run: | export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON a=gnu23; b=gnu++23; if test "X${{ matrix.use_cxx2b }}" = X1; then a=gnu2x; b=gnu++2b; fi - make -C "upx with space" UPX_XTARGET=clang-cxx23-static CC="clang -std=$a -static" CXX="clang++ -std=$b -static" + make -C "upx with space" UPX_XTARGET=clang-static-cxx23 CC="clang -static -std=$a" CXX="clang++ -static -std=$b" - name: ${{ format('Build clang C++23 Debug with {0}', env.clang_package) }} if: matrix.use_cxx23 || matrix.use_cxx2b run: | export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON a=gnu23; b=gnu++23; if test "X${{ matrix.use_cxx2b }}" = X1; then a=gnu2x; b=gnu++2b; fi - make -C "upx with space" UPX_XTARGET=clang-cxx23-static CC="clang -std=$a -static" CXX="clang++ -std=$b -static" xtarget/debug + make -C "upx with space" UPX_XTARGET=clang-static-cxx23 CC="clang -static -std=$a" CXX="clang++ -static -std=$b" xtarget/debug - name: ${{ format('Build gcc C++23 Release with {0}', env.gcc_package) }} if: matrix.use_cxx23 || matrix.use_cxx2b run: | export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON a=gnu23; b=gnu++23; if test "X${{ matrix.use_cxx2b }}" = X1; then a=gnu2x; b=gnu++2b; fi - make -C "upx with space" UPX_XTARGET=gcc-cxx23-static CC="gcc -std=$a -static" CXX="g++ -std=$b -static" + make -C "upx with space" UPX_XTARGET=gcc-static-cxx23 CC="gcc -static -std=$a" CXX="g++ -static -std=$b" - name: ${{ format('Build gcc C++23 Debug with {0}', env.gcc_package) }} if: matrix.use_cxx23 || matrix.use_cxx2b run: | export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON a=gnu23; b=gnu++23; if test "X${{ matrix.use_cxx2b }}" = X1; then a=gnu2x; b=gnu++2b; fi - make -C "upx with space" UPX_XTARGET=gcc-cxx23-static CC="gcc -std=$a -static" CXX="g++ -std=$b -static" xtarget/debug + make -C "upx with space" UPX_XTARGET=gcc-static-cxx23 CC="gcc -static -std=$a" CXX="g++ -static -std=$b" xtarget/debug # build with -flto - name: ${{ format('Build clang LTO Release with {0}', env.clang_package) }} if: matrix.use_lto run: | - make -C "upx with space" UPX_XTARGET=clang-cxxlto-static CC="clang -flto -static" CXX="clang++ -flto -static" + make -C "upx with space" UPX_XTARGET=clang-static-cxxlto CC="clang -static -flto" CXX="clang++ -static -flto" - name: ${{ format('Build clang LTO Debug with {0}', env.clang_package) }} if: matrix.use_lto run: | - make -C "upx with space" UPX_XTARGET=clang-cxxlto-static CC="clang -flto -static" CXX="clang++ -flto -static" xtarget/debug + make -C "upx with space" UPX_XTARGET=clang-static-cxxlto CC="clang -static -flto" CXX="clang++ -static -flto" xtarget/debug - name: ${{ format('Build gcc LTO Release with {0}', env.gcc_package) }} if: matrix.use_lto run: | - make -C "upx with space" UPX_XTARGET=gcc-cxxlto-static CC="gcc -flto -static" CXX="g++ -flto -static" + make -C "upx with space" UPX_XTARGET=gcc-static-cxxlto CC="gcc -static -flto" CXX="g++ -static -flto" - name: ${{ format('Build gcc LTO Debug with {0}', env.gcc_package) }} if: matrix.use_lto run: | - make -C "upx with space" UPX_XTARGET=gcc-cxxlto-static CC="gcc -flto -static" CXX="g++ -flto -static" xtarget/debug + make -C "upx with space" UPX_XTARGET=gcc-static-cxxlto CC="gcc -static -flto" CXX="g++ -static -flto" xtarget/debug - { name: 'Strip release binaries', run: 'strip -p --strip-unneeded "upx with space"/build/*/*/release/upx' } diff --git a/.github/workflows/weekly-ci-cc-zigcc.yml b/.github/workflows/weekly-ci-cc-zigcc.yml index 68a9ed5f..6d10a4ce 100644 --- a/.github/workflows/weekly-ci-cc-zigcc.yml +++ b/.github/workflows/weekly-ci-cc-zigcc.yml @@ -10,8 +10,8 @@ on: env: CMAKE_REQUIRED_QUIET: OFF DEBIAN_FRONTEND: noninteractive - # 2023-09-19 - ZIG_DIST_VERSION: 0.12.0-dev.415+5af5d87ad + # 2023-09-25 + ZIG_DIST_VERSION: 0.12.0-dev.573+c9413a880 jobs: job-linux-zigcc: # uses cmake + make diff --git a/.github/workflows/weekly-ci-rt-checkers.yml b/.github/workflows/weekly-ci-rt-checkers.yml index 2c2031dc..2b538b02 100644 --- a/.github/workflows/weekly-ci-rt-checkers.yml +++ b/.github/workflows/weekly-ci-rt-checkers.yml @@ -82,7 +82,7 @@ jobs: - name: 'Run testsuite clang-asan' if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: ASAN not supported run: | - export ASAN_OPTIONS=detect_invalid_pointer_pairs=2 + export ASAN_OPTIONS="detect_invalid_pointer_pairs=2" env -C build/xtarget/clang-asan/$release "$PWD"/misc/testsuite/upx_testsuite_1.sh - name: 'Run testsuite clang-msan' if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: MSAN not supported diff --git a/CMakeLists.txt b/CMakeLists.txt index 853e8ddc..50ab5976 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ endif() # compilation config options if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git") - # permissive config defaults when building from source code release tarball + # permissive config defaults when building from source code tarball option(UPX_CONFIG_DISABLE_GITREV "Do not compile with default Git version info." ON) option(UPX_CONFIG_DISABLE_SANITIZE "Do not compile with default sanitize options." ON) option(UPX_CONFIG_DISABLE_WSTRICT "Do not compile with strict compiler warnings." ON) @@ -226,12 +226,14 @@ if(NOT CMAKE_C_COMPILER_ID MATCHES "^MSVC") set(CMAKE_C_FLAGS_RELEASE "${a}" CACHE STRING "Flags used by the C compiler during RELEASE builds." FORCE) set(CMAKE_CXX_FLAGS_RELEASE "${b}" CACHE STRING "Flags used by the CXX compiler during RELEASE builds." FORCE) endif() -if(MSVC_FRONTEND) +if(MSVC_FRONTEND OR WIN32) # disable silly warnings about using "deprecated" POSIX functions like fopen() add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) add_definitions(-D_CRT_NONSTDC_NO_WARNINGS) add_definitions(-D_CRT_SECURE_NO_DEPRECATE) add_definitions(-D_CRT_SECURE_NO_WARNINGS) +endif() +if(MSVC_FRONTEND) # use -funsigned-char; set __cplusplus according to selected C++ standard add_definitions(-J -Zc:__cplusplus) if(CMAKE_C_COMPILER_ID MATCHES "^MSVC") diff --git a/src/check/dt_cxxlib.cpp b/src/check/dt_cxxlib.cpp index 0c918877..2c7f60ed 100644 --- a/src/check/dt_cxxlib.cpp +++ b/src/check/dt_cxxlib.cpp @@ -30,6 +30,7 @@ // compile-time checks **************************************************************************/ +// need extra parenthesis because the C preprocessor does not understand C++ templates ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_all_v) ) ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_all_v) ) ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_all_v) ) diff --git a/src/except.cpp b/src/except.cpp index 2509fc21..c0ca7190 100644 --- a/src/except.cpp +++ b/src/except.cpp @@ -142,7 +142,7 @@ void throwEOFException(const char *msg, int e) { } /************************************************************************* -// +// varargs overloads **************************************************************************/ template <> @@ -166,7 +166,7 @@ void throwCantUnpack(const char *format, ...) { } /************************************************************************* -// +// util **************************************************************************/ void assertFailed(const char *expr, const char *file, int line, const char *func) noexcept { @@ -191,7 +191,7 @@ const char *prettyName(const char *n) noexcept { n++; else if (*n == ' ') n++; - else if (strncmp(n, "class ", 6) == 0) // Visual C++ + else if (strncmp(n, "class ", 6) == 0) // Visual C++ (msvc) n += 6; else break; diff --git a/src/file.cpp b/src/file.cpp index 370905de..ce43cc27 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -65,7 +65,7 @@ } /************************************************************************* -// +// FileBase **************************************************************************/ FileBase::~FileBase() may_throw { @@ -160,7 +160,7 @@ void FileBase::set_extent(upx_off_t offset, upx_off_t length) { upx_off_t FileBase::st_size() const { return _length; } /************************************************************************* -// +// InputFile **************************************************************************/ void InputFile::sopen(const char *name, int flags, int shflags) { @@ -210,7 +210,7 @@ upx_off_t InputFile::seek(upx_off_t off, int whence) { upx_off_t InputFile::st_size_orig() const { return _length_orig; } /************************************************************************* -// +// OutputFile **************************************************************************/ void OutputFile::sopen(const char *name, int flags, int shflags, int mode) { diff --git a/src/ui.cpp b/src/ui.cpp index d1233ae0..8be81896 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -25,8 +25,8 @@ */ -// INFO: not thread-safe; assumes a single UiPacker instance that -// is exclusively called from main thread +// INFO: not thread-safe; instantiated and used by class Packer, and the +// static (global) variables are also updated in work.cpp #include "conf.h" #include "file.h" @@ -128,7 +128,7 @@ static void init_global_constants(void) noexcept { static const char *mkline(upx_uint64_t fu_len, upx_uint64_t fc_len, upx_uint64_t u_len, upx_uint64_t c_len, const char *format_name, const char *filename, bool decompress = false) { - static char buf[2048]; + static char buf[2048]; // static! char r[7 + 1]; char fn[15 + 1]; const char *f; diff --git a/src/ui.h b/src/ui.h index 5f0f07b1..f65b8103 100644 --- a/src/ui.h +++ b/src/ui.h @@ -93,7 +93,7 @@ protected: struct State; OwningPointer(State) s = nullptr; // owner - // totals + // static totals static unsigned total_files; static unsigned total_files_done; static upx_uint64_t total_c_len; diff --git a/src/util/cxxlib.h b/src/util/cxxlib.h index 9cfc9b8c..ba6b77c0 100644 --- a/src/util/cxxlib.h +++ b/src/util/cxxlib.h @@ -38,7 +38,7 @@ namespace upx { // is_bounded_array: identical to C++20 std::is_bounded_array template struct is_bounded_array : public std::false_type {}; -template +template struct is_bounded_array : public std::true_type {}; template inline constexpr bool is_bounded_array_v = is_bounded_array::value; @@ -57,7 +57,7 @@ inline constexpr bool is_same_any_v = is_same_any::value; // util **************************************************************************/ -template +template struct UnsignedSizeOf { static_assert(Size >= 1 && Size <= UPX_RSIZE_MAX_MEM); static constexpr unsigned value = unsigned(Size); @@ -65,8 +65,12 @@ struct UnsignedSizeOf { class noncopyable { protected: - inline noncopyable() noexcept {} - inline ~noncopyable() noexcept = default; + forceinline constexpr noncopyable() noexcept {} +#if __cplusplus >= 202002L + forceinline constexpr ~noncopyable() noexcept = default; +#else + forceinline ~noncopyable() noexcept = default; +#endif private: noncopyable(const noncopyable &) noexcept DELETED_FUNCTION; // copy constructor noncopyable &operator=(const noncopyable &) noexcept DELETED_FUNCTION; // copy assignment @@ -75,7 +79,7 @@ private: }; namespace compile_time { -constexpr size_t string_len(const char *a) { return *a == '\0' ? 0 : 1 + string_len(a + 1); } +constexpr std::size_t string_len(const char *a) { return *a == '\0' ? 0 : 1 + string_len(a + 1); } constexpr bool string_eq(const char *a, const char *b) { return *a == *b && (*a == '\0' || string_eq(a + 1, b + 1)); } @@ -107,7 +111,11 @@ struct TriBool final { forceinline constexpr TriBool() noexcept {} forceinline constexpr TriBool(value_type x) noexcept : value(x) {} constexpr TriBool(promoted_type x) noexcept : value(x == 0 ? False : (x == 1 ? True : Third)) {} +#if __cplusplus >= 202002L + forceinline constexpr ~TriBool() noexcept = default; +#else forceinline ~TriBool() noexcept = default; +#endif // explicit conversion to bool // checks for > 0, so ThirdValue determines if Third is false (the default) or true explicit constexpr operator bool() const noexcept { return value > False; } @@ -221,23 +229,23 @@ struct OwningPointer final { typedef typename std::add_lvalue_reference::type const_reference; typedef typename std::add_pointer::type pointer; typedef typename std::add_pointer::type const_pointer; - inline OwningPointer(pointer p) noexcept : ptr(p) {} - inline operator pointer() noexcept { return ptr; } - inline operator const_pointer() const noexcept { return ptr; } - inline reference operator*() noexcept { return *ptr; } - inline const_reference operator*() const noexcept { return *ptr; } - inline pointer operator->() noexcept { return ptr; } - inline const_pointer operator->() const noexcept { return ptr; } + constexpr OwningPointer(pointer p) noexcept : ptr(p) {} + constexpr operator pointer() noexcept { return ptr; } + constexpr operator const_pointer() const noexcept { return ptr; } + constexpr reference operator*() noexcept { return *ptr; } + constexpr const_reference operator*() const noexcept { return *ptr; } + constexpr pointer operator->() noexcept { return ptr; } + constexpr const_pointer operator->() const noexcept { return ptr; } private: pointer ptr; reference operator[](std::ptrdiff_t) noexcept = delete; const_reference operator[](std::ptrdiff_t) const noexcept = delete; -#if 1 // fun with C++ +#if 0 // fun with C++ // disable common "new" and ALL "delete" operators - static void *operator new(size_t) = delete; - static void *operator new[](size_t) = delete; - static void *operator new(size_t, void *) = delete; - static void *operator new[](size_t, void *) = delete; + static void *operator new(std::size_t) = delete; + static void *operator new[](std::size_t) = delete; + static void *operator new(std::size_t, void *) = delete; + static void *operator new[](std::size_t, void *) = delete; // replaceable usual deallocation functions (8) static void operator delete(void *) noexcept = delete; static void operator delete[](void *) noexcept = delete; @@ -275,6 +283,8 @@ inline void owner_delete(OwningPointer(T)(&object)) noexcept { delete (T *) object; object = nullptr; } + assert_noexcept((T *) object == nullptr); + assert_noexcept(object == nullptr); } // disable some overloads @@ -282,7 +292,7 @@ inline void owner_delete(OwningPointer(T)(&object)) noexcept { template inline void owner_delete(T (&array)[]) noexcept DELETED_FUNCTION; #endif -template +template inline void owner_delete(T (&array)[N]) noexcept DELETED_FUNCTION; } // namespace upx diff --git a/src/util/membuffer.cpp b/src/util/membuffer.cpp index 145a5487..50eb90bb 100644 --- a/src/util/membuffer.cpp +++ b/src/util/membuffer.cpp @@ -96,8 +96,9 @@ void *MemBuffer::subref_impl(const char *errfmt, size_t skip, size_t take) { return ptr + skip; } -static forceinline size_t umax(size_t a, size_t b) { return (a >= b) ? a : b; } +static forceinline constexpr size_t umax(size_t a, size_t b) { return (a >= b) ? a : b; } +/*static*/ unsigned MemBuffer::getSizeForCompression(unsigned uncompressed_size, unsigned extra) { if (uncompressed_size == 0) throwCantPack("invalid uncompressed_size"); @@ -112,6 +113,7 @@ unsigned MemBuffer::getSizeForCompression(unsigned uncompressed_size, unsigned e return ACC_ICONV(unsigned, bytes); } +/*static*/ unsigned MemBuffer::getSizeForDecompression(unsigned uncompressed_size, unsigned extra) { if (uncompressed_size == 0) throwCantPack("invalid uncompressed_size"); diff --git a/src/util/util.cpp b/src/util/util.cpp index 439dbd58..6ad19007 100644 --- a/src/util/util.cpp +++ b/src/util/util.cpp @@ -381,16 +381,17 @@ void upx_std_stable_sort(void *array, size_t n, upx_compare_func_t compare) { struct alignas(1) element_type { byte data[ElementSize]; }; static_assert(sizeof(element_type) == ElementSize); static_assert(alignof(element_type) == 1); - auto cmp = [compare](const element_type &a, const element_type &b) -> bool { + auto less = [compare](const element_type &a, const element_type &b) -> bool { return compare(&a, &b) < 0; }; - std::stable_sort((element_type *) array, (element_type *) array + n, cmp); + std::stable_sort((element_type *) array, (element_type *) array + n, less); #endif } #if UPX_CONFIG_USE_STABLE_SORT -// instantiate function templates for all element sizes we need -// efficient, but code size bloat +// instantiate function templates for all element sizes we need; efficient run time, but code size +// bloat (about 4KiB code size for each function with my current libstdc++); not really needed as +// libc qsort() is good enough for our use cases template void upx_std_stable_sort<1>(void *, size_t, upx_compare_func_t); template void upx_std_stable_sort<2>(void *, size_t, upx_compare_func_t); template void upx_std_stable_sort<4>(void *, size_t, upx_compare_func_t); @@ -428,7 +429,7 @@ struct TestSortAllPermutations { } while (std::next_permutation(perm, perm + n)); return num_perms; } - static bool test_permutations(upx_sort_func_t sort) { + static noinline bool test_permutations(upx_sort_func_t sort) { bool ok = true; ok &= (test(sort, 0) == 0); ok &= (test(sort, 1) == 1); @@ -653,9 +654,9 @@ TEST_CASE("find") { } int mem_replace(void *buf, int blen, const void *what, int wlen, const void *replacement) noexcept { - byte *b = (byte *) buf; + byte *const b = (byte *) buf; int boff = 0; - int n = 0; + int count = 0; while (blen - boff >= wlen) { int off = find(b + boff, blen - boff, what, wlen); @@ -664,9 +665,9 @@ int mem_replace(void *buf, int blen, const void *what, int wlen, const void *rep boff += off; memcpy(b + boff, replacement, wlen); boff += wlen; - n++; + count++; } - return n; + return count; } TEST_CASE("mem_replace") { diff --git a/src/util/util.h b/src/util/util.h index 469978cf..9c030fea 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -143,12 +143,12 @@ void upx_std_stable_sort(void *array, size_t n, upx_compare_func_t compare); // use std::stable_sort(); requires that "element_size" is constexpr! #define upx_qsort(a, n, element_size, compare) upx_std_stable_sort<(element_size)>(a, n, compare) #else -// use libc qsort() +// use libc qsort(); good enough for our use cases #define upx_qsort qsort #endif /************************************************************************* -// misc. support functions +// misc support functions **************************************************************************/ int find(const void *b, int blen, const void *what, int wlen) noexcept;