CI updates

This commit is contained in:
Markus F.X.J. Oberhumer 2023-09-25 13:47:43 +02:00
parent 98a77dde00
commit eb021accd1
17 changed files with 86 additions and 65 deletions

View File

@ -12,8 +12,8 @@ env:
CMAKE_REQUIRED_QUIET: OFF CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
UPX_CMAKE_BUILD_FLAGS: --verbose UPX_CMAKE_BUILD_FLAGS: --verbose
# 2023-09-19 # 2023-09-25
ZIG_DIST_VERSION: 0.12.0-dev.415+5af5d87ad ZIG_DIST_VERSION: 0.12.0-dev.573+c9413a880
jobs: jobs:
job-rebuild-and-verify-stubs: job-rebuild-and-verify-stubs:

View File

@ -30,8 +30,8 @@ jobs:
echo "installing shells: $shells" echo "installing shells: $shells"
apk update && apk upgrade && apk add ccache g++ git $shells apk update && apk upgrade && apk add ccache g++ git $shells
# enable ccache and some warnings # enable ccache and some warnings
warn="-Wall -Wextra -Werror" xflags="-static -Wall -Wextra -Werror"
echo -e "CC=ccache gcc $warn\nCXX=ccache g++ -std=gnu++17 $warn" >> $GITHUB_ENV 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??) # this seems to be needed when running in a container (beause of UID mismatch??)
git config --global --add safe.directory '*' git config --global --add safe.directory '*'
# create user upx:upx 2000:2000 for file system tests below ("sudo") # create user upx:upx 2000:2000 for file system tests below ("sudo")

View File

@ -18,7 +18,8 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: 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) # # cl (msvc)
# - { os: windows-2019, cc: cl, cxx: cl, vsversion: 2019, arch: amd64 } # - { 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_arm64 }
@ -28,6 +29,8 @@ jobs:
# - { os: windows-2022, cc: cl, cxx: cl, vsversion: 2022, arch: amd64_x86 } # - { os: windows-2022, cc: cl, cxx: cl, vsversion: 2022, arch: amd64_x86 }
# # clang-cl # # clang-cl
# - { os: windows-2022, cc: clang-cl, cxx: clang-cl, vsversion: 2022, arch: amd64 } # - { 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) # gcc (mingw-gcc)
- { os: windows-2022, cc: gcc, cxx: 'g++', arch: amd64, xflags: '-static' } - { os: windows-2022, cc: gcc, cxx: 'g++', arch: amd64, xflags: '-static' }
env: env:

View File

@ -18,7 +18,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: 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 }
- { os: windows-2019, cc: cl, cxx: cl, vsversion: 2019, arch: amd64_arm64 } - { os: windows-2019, cc: cl, cxx: cl, vsversion: 2019, arch: amd64_arm64 }
- { os: windows-2019, cc: cl, cxx: cl, vsversion: 2019, arch: amd64_x86 } - { 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 } - { os: windows-2022, cc: cl, cxx: cl, vsversion: 2022, arch: amd64_x86 }
# clang-cl # clang-cl
- { os: windows-2022, cc: clang-cl, cxx: clang-cl, vsversion: 2022, arch: amd64 } - { 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) # gcc (mingw-gcc)
- { os: windows-2022, cc: gcc, cxx: 'g++', arch: amd64, xflags: '-static' } - { os: windows-2022, cc: gcc, cxx: 'g++', arch: amd64, xflags: '-static' }
env: env:
@ -48,7 +50,7 @@ jobs:
shell: bash shell: bash
run: | run: |
command -v ninja >/dev/null || choco install -y --no-progress ninja 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 echo "xtarget=$xtarget" >> $GITHUB_ENV
- name: 'Build cmake Ninja Debug' - name: 'Build cmake Ninja Debug'
shell: bash shell: bash

View File

@ -81,66 +81,66 @@ jobs:
if: matrix.use_cxx20 if: matrix.use_cxx20
run: | run: |
export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON 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) }} - name: ${{ format('Build clang C++20 Debug with {0}', env.clang_package) }}
if: matrix.use_cxx20 if: matrix.use_cxx20
run: | run: |
export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON 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) }} - name: ${{ format('Build gcc C++20 Release with {0}', env.gcc_package) }}
if: matrix.use_cxx20 if: matrix.use_cxx20
run: | run: |
export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON 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) }} - name: ${{ format('Build gcc C++20 Debug with {0}', env.gcc_package) }}
if: matrix.use_cxx20 if: matrix.use_cxx20
run: | run: |
export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON 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) }} - name: ${{ format('Build clang C++23 Release with {0}', env.clang_package) }}
if: matrix.use_cxx23 || matrix.use_cxx2b if: matrix.use_cxx23 || matrix.use_cxx2b
run: | run: |
export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON 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 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) }} - name: ${{ format('Build clang C++23 Debug with {0}', env.clang_package) }}
if: matrix.use_cxx23 || matrix.use_cxx2b if: matrix.use_cxx23 || matrix.use_cxx2b
run: | run: |
export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON 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 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) }} - name: ${{ format('Build gcc C++23 Release with {0}', env.gcc_package) }}
if: matrix.use_cxx23 || matrix.use_cxx2b if: matrix.use_cxx23 || matrix.use_cxx2b
run: | run: |
export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON 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 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) }} - name: ${{ format('Build gcc C++23 Debug with {0}', env.gcc_package) }}
if: matrix.use_cxx23 || matrix.use_cxx2b if: matrix.use_cxx23 || matrix.use_cxx2b
run: | run: |
export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON 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 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 # build with -flto
- name: ${{ format('Build clang LTO Release with {0}', env.clang_package) }} - name: ${{ format('Build clang LTO Release with {0}', env.clang_package) }}
if: matrix.use_lto if: matrix.use_lto
run: | 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) }} - name: ${{ format('Build clang LTO Debug with {0}', env.clang_package) }}
if: matrix.use_lto if: matrix.use_lto
run: | 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) }} - name: ${{ format('Build gcc LTO Release with {0}', env.gcc_package) }}
if: matrix.use_lto if: matrix.use_lto
run: | 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) }} - name: ${{ format('Build gcc LTO Debug with {0}', env.gcc_package) }}
if: matrix.use_lto if: matrix.use_lto
run: | 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' } - { name: 'Strip release binaries', run: 'strip -p --strip-unneeded "upx with space"/build/*/*/release/upx' }

View File

@ -10,8 +10,8 @@ on:
env: env:
CMAKE_REQUIRED_QUIET: OFF CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
# 2023-09-19 # 2023-09-25
ZIG_DIST_VERSION: 0.12.0-dev.415+5af5d87ad ZIG_DIST_VERSION: 0.12.0-dev.573+c9413a880
jobs: jobs:
job-linux-zigcc: # uses cmake + make job-linux-zigcc: # uses cmake + make

View File

@ -82,7 +82,7 @@ jobs:
- name: 'Run testsuite clang-asan' - name: 'Run testsuite clang-asan'
if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: ASAN not supported if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: ASAN not supported
run: | 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 env -C build/xtarget/clang-asan/$release "$PWD"/misc/testsuite/upx_testsuite_1.sh
- name: 'Run testsuite clang-msan' - name: 'Run testsuite clang-msan'
if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: MSAN not supported if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: MSAN not supported

View File

@ -16,7 +16,7 @@ endif()
# compilation config options # compilation config options
if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git") 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_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_SANITIZE "Do not compile with default sanitize options." ON)
option(UPX_CONFIG_DISABLE_WSTRICT "Do not compile with strict compiler warnings." 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_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) set(CMAKE_CXX_FLAGS_RELEASE "${b}" CACHE STRING "Flags used by the CXX compiler during RELEASE builds." FORCE)
endif() endif()
if(MSVC_FRONTEND) if(MSVC_FRONTEND OR WIN32)
# disable silly warnings about using "deprecated" POSIX functions like fopen() # disable silly warnings about using "deprecated" POSIX functions like fopen()
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
add_definitions(-D_CRT_NONSTDC_NO_WARNINGS) add_definitions(-D_CRT_NONSTDC_NO_WARNINGS)
add_definitions(-D_CRT_SECURE_NO_DEPRECATE) add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()
if(MSVC_FRONTEND)
# use -funsigned-char; set __cplusplus according to selected C++ standard # use -funsigned-char; set __cplusplus according to selected C++ standard
add_definitions(-J -Zc:__cplusplus) add_definitions(-J -Zc:__cplusplus)
if(CMAKE_C_COMPILER_ID MATCHES "^MSVC") if(CMAKE_C_COMPILER_ID MATCHES "^MSVC")

View File

@ -30,6 +30,7 @@
// compile-time checks // 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<int>) ) ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_all_v<int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_all_v<int, int>) ) ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_all_v<int, int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_all_v<int, int, int>) ) ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_all_v<int, int, int>) )

View File

@ -142,7 +142,7 @@ void throwEOFException(const char *msg, int e) {
} }
/************************************************************************* /*************************************************************************
// // varargs overloads
**************************************************************************/ **************************************************************************/
template <> 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 { 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++; n++;
else if (*n == ' ') else if (*n == ' ')
n++; n++;
else if (strncmp(n, "class ", 6) == 0) // Visual C++ else if (strncmp(n, "class ", 6) == 0) // Visual C++ (msvc)
n += 6; n += 6;
else else
break; break;

View File

@ -65,7 +65,7 @@
} }
/************************************************************************* /*************************************************************************
// // FileBase
**************************************************************************/ **************************************************************************/
FileBase::~FileBase() may_throw { 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; } upx_off_t FileBase::st_size() const { return _length; }
/************************************************************************* /*************************************************************************
// // InputFile
**************************************************************************/ **************************************************************************/
void InputFile::sopen(const char *name, int flags, int shflags) { 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; } upx_off_t InputFile::st_size_orig() const { return _length_orig; }
/************************************************************************* /*************************************************************************
// // OutputFile
**************************************************************************/ **************************************************************************/
void OutputFile::sopen(const char *name, int flags, int shflags, int mode) { void OutputFile::sopen(const char *name, int flags, int shflags, int mode) {

View File

@ -25,8 +25,8 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
// INFO: not thread-safe; assumes a single UiPacker instance that // INFO: not thread-safe; instantiated and used by class Packer, and the
// is exclusively called from main thread // static (global) variables are also updated in work.cpp
#include "conf.h" #include "conf.h"
#include "file.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, 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, upx_uint64_t c_len, const char *format_name, const char *filename,
bool decompress = false) { bool decompress = false) {
static char buf[2048]; static char buf[2048]; // static!
char r[7 + 1]; char r[7 + 1];
char fn[15 + 1]; char fn[15 + 1];
const char *f; const char *f;

View File

@ -93,7 +93,7 @@ protected:
struct State; struct State;
OwningPointer(State) s = nullptr; // owner OwningPointer(State) s = nullptr; // owner
// totals // static totals
static unsigned total_files; static unsigned total_files;
static unsigned total_files_done; static unsigned total_files_done;
static upx_uint64_t total_c_len; static upx_uint64_t total_c_len;

View File

@ -38,7 +38,7 @@ namespace upx {
// is_bounded_array: identical to C++20 std::is_bounded_array // is_bounded_array: identical to C++20 std::is_bounded_array
template <class T> template <class T>
struct is_bounded_array : public std::false_type {}; struct is_bounded_array : public std::false_type {};
template <class T, size_t N> template <class T, std::size_t N>
struct is_bounded_array<T[N]> : public std::true_type {}; struct is_bounded_array<T[N]> : public std::true_type {};
template <class T> template <class T>
inline constexpr bool is_bounded_array_v = is_bounded_array<T>::value; inline constexpr bool is_bounded_array_v = is_bounded_array<T>::value;
@ -57,7 +57,7 @@ inline constexpr bool is_same_any_v = is_same_any<T, Ts...>::value;
// util // util
**************************************************************************/ **************************************************************************/
template <size_t Size> template <std::size_t Size>
struct UnsignedSizeOf { struct UnsignedSizeOf {
static_assert(Size >= 1 && Size <= UPX_RSIZE_MAX_MEM); static_assert(Size >= 1 && Size <= UPX_RSIZE_MAX_MEM);
static constexpr unsigned value = unsigned(Size); static constexpr unsigned value = unsigned(Size);
@ -65,8 +65,12 @@ struct UnsignedSizeOf {
class noncopyable { class noncopyable {
protected: protected:
inline noncopyable() noexcept {} forceinline constexpr noncopyable() noexcept {}
inline ~noncopyable() noexcept = default; #if __cplusplus >= 202002L
forceinline constexpr ~noncopyable() noexcept = default;
#else
forceinline ~noncopyable() noexcept = default;
#endif
private: private:
noncopyable(const noncopyable &) noexcept DELETED_FUNCTION; // copy constructor noncopyable(const noncopyable &) noexcept DELETED_FUNCTION; // copy constructor
noncopyable &operator=(const noncopyable &) noexcept DELETED_FUNCTION; // copy assignment noncopyable &operator=(const noncopyable &) noexcept DELETED_FUNCTION; // copy assignment
@ -75,7 +79,7 @@ private:
}; };
namespace compile_time { 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) { constexpr bool string_eq(const char *a, const char *b) {
return *a == *b && (*a == '\0' || string_eq(a + 1, b + 1)); 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() noexcept {}
forceinline constexpr TriBool(value_type x) noexcept : value(x) {} forceinline constexpr TriBool(value_type x) noexcept : value(x) {}
constexpr TriBool(promoted_type x) noexcept : value(x == 0 ? False : (x == 1 ? True : Third)) {} 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; forceinline ~TriBool() noexcept = default;
#endif
// explicit conversion to bool // explicit conversion to bool
// checks for > 0, so ThirdValue determines if Third is false (the default) or true // checks for > 0, so ThirdValue determines if Third is false (the default) or true
explicit constexpr operator bool() const noexcept { return value > False; } explicit constexpr operator bool() const noexcept { return value > False; }
@ -221,23 +229,23 @@ struct OwningPointer final {
typedef typename std::add_lvalue_reference<const T>::type const_reference; typedef typename std::add_lvalue_reference<const T>::type const_reference;
typedef typename std::add_pointer<T>::type pointer; typedef typename std::add_pointer<T>::type pointer;
typedef typename std::add_pointer<const T>::type const_pointer; typedef typename std::add_pointer<const T>::type const_pointer;
inline OwningPointer(pointer p) noexcept : ptr(p) {} constexpr OwningPointer(pointer p) noexcept : ptr(p) {}
inline operator pointer() noexcept { return ptr; } constexpr operator pointer() noexcept { return ptr; }
inline operator const_pointer() const noexcept { return ptr; } constexpr operator const_pointer() const noexcept { return ptr; }
inline reference operator*() noexcept { return *ptr; } constexpr reference operator*() noexcept { return *ptr; }
inline const_reference operator*() const noexcept { return *ptr; } constexpr const_reference operator*() const noexcept { return *ptr; }
inline pointer operator->() noexcept { return ptr; } constexpr pointer operator->() noexcept { return ptr; }
inline const_pointer operator->() const noexcept { return ptr; } constexpr const_pointer operator->() const noexcept { return ptr; }
private: private:
pointer ptr; pointer ptr;
reference operator[](std::ptrdiff_t) noexcept = delete; reference operator[](std::ptrdiff_t) noexcept = delete;
const_reference operator[](std::ptrdiff_t) const 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 // disable common "new" and ALL "delete" operators
static void *operator new(size_t) = delete; static void *operator new(std::size_t) = delete;
static void *operator new[](size_t) = delete; static void *operator new[](std::size_t) = delete;
static void *operator new(size_t, void *) = delete; static void *operator new(std::size_t, void *) = delete;
static void *operator new[](size_t, void *) = delete; static void *operator new[](std::size_t, void *) = delete;
// replaceable usual deallocation functions (8) // replaceable usual deallocation functions (8)
static void operator delete(void *) noexcept = delete; static void operator delete(void *) noexcept = delete;
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; delete (T *) object;
object = nullptr; object = nullptr;
} }
assert_noexcept((T *) object == nullptr);
assert_noexcept(object == nullptr);
} }
// disable some overloads // disable some overloads
@ -282,7 +292,7 @@ inline void owner_delete(OwningPointer(T)(&object)) noexcept {
template <class T> template <class T>
inline void owner_delete(T (&array)[]) noexcept DELETED_FUNCTION; inline void owner_delete(T (&array)[]) noexcept DELETED_FUNCTION;
#endif #endif
template <class T, size_t N> template <class T, std::size_t N>
inline void owner_delete(T (&array)[N]) noexcept DELETED_FUNCTION; inline void owner_delete(T (&array)[N]) noexcept DELETED_FUNCTION;
} // namespace upx } // namespace upx

View File

@ -96,8 +96,9 @@ void *MemBuffer::subref_impl(const char *errfmt, size_t skip, size_t take) {
return ptr + skip; 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) { unsigned MemBuffer::getSizeForCompression(unsigned uncompressed_size, unsigned extra) {
if (uncompressed_size == 0) if (uncompressed_size == 0)
throwCantPack("invalid uncompressed_size"); throwCantPack("invalid uncompressed_size");
@ -112,6 +113,7 @@ unsigned MemBuffer::getSizeForCompression(unsigned uncompressed_size, unsigned e
return ACC_ICONV(unsigned, bytes); return ACC_ICONV(unsigned, bytes);
} }
/*static*/
unsigned MemBuffer::getSizeForDecompression(unsigned uncompressed_size, unsigned extra) { unsigned MemBuffer::getSizeForDecompression(unsigned uncompressed_size, unsigned extra) {
if (uncompressed_size == 0) if (uncompressed_size == 0)
throwCantPack("invalid uncompressed_size"); throwCantPack("invalid uncompressed_size");

View File

@ -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]; }; struct alignas(1) element_type { byte data[ElementSize]; };
static_assert(sizeof(element_type) == ElementSize); static_assert(sizeof(element_type) == ElementSize);
static_assert(alignof(element_type) == 1); 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; 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 #endif
} }
#if UPX_CONFIG_USE_STABLE_SORT #if UPX_CONFIG_USE_STABLE_SORT
// instantiate function templates for all element sizes we need // instantiate function templates for all element sizes we need; efficient run time, but code size
// efficient, but code size bloat // 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<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<2>(void *, size_t, upx_compare_func_t);
template void upx_std_stable_sort<4>(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)); } while (std::next_permutation(perm, perm + n));
return num_perms; 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; bool ok = true;
ok &= (test(sort, 0) == 0); ok &= (test(sort, 0) == 0);
ok &= (test(sort, 1) == 1); 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 { 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 boff = 0;
int n = 0; int count = 0;
while (blen - boff >= wlen) { while (blen - boff >= wlen) {
int off = find(b + boff, blen - boff, what, 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; boff += off;
memcpy(b + boff, replacement, wlen); memcpy(b + boff, replacement, wlen);
boff += wlen; boff += wlen;
n++; count++;
} }
return n; return count;
} }
TEST_CASE("mem_replace") { TEST_CASE("mem_replace") {

View File

@ -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! // 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) #define upx_qsort(a, n, element_size, compare) upx_std_stable_sort<(element_size)>(a, n, compare)
#else #else
// use libc qsort() // use libc qsort(); good enough for our use cases
#define upx_qsort qsort #define upx_qsort qsort
#endif #endif
/************************************************************************* /*************************************************************************
// misc. support functions // misc support functions
**************************************************************************/ **************************************************************************/
int find(const void *b, int blen, const void *what, int wlen) noexcept; int find(const void *b, int blen, const void *what, int wlen) noexcept;