diff --git a/CMakeLists.txt b/CMakeLists.txt index e2d40edd..97e65d6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -523,15 +523,9 @@ endif() # extra sanity checks to detect incompatible C vs CXX settings if(NOT UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK) -if(NOT ",${CMAKE_C_PLATFORM_ID}," STREQUAL ",${CMAKE_CXX_PLATFORM_ID},") - message(FATAL_ERROR "ERROR: CMAKE_C_PLATFORM_ID CMAKE_CXX_PLATFORM_ID mismatch") -endif() -if(NOT ",${CMAKE_C_COMPILER_ABI}," STREQUAL ",${CMAKE_CXX_COMPILER_ABI},") - message(FATAL_ERROR "ERROR: CMAKE_C_COMPILER_ABI CMAKE_CXX_COMPILER_ABI mismatch") -endif() -if(NOT ",${CMAKE_C_COMPILER_FRONTEND_VARIANT}," STREQUAL ",${CMAKE_CXX_COMPILER_FRONTEND_VARIANT},") - message(FATAL_ERROR "ERROR: CMAKE_C_COMPILER_FRONTEND_VARIANT CMAKE_CXX_COMPILER_FRONTEND_VARIANT mismatch") -endif() + upx_platform_check_mismatch(CMAKE_C_PLATFORM_ID CMAKE_CXX_PLATFORM_ID) + upx_platform_check_mismatch(CMAKE_C_COMPILER_ABI CMAKE_CXX_COMPILER_ABI) + upx_platform_check_mismatch(CMAKE_C_COMPILER_FRONTEND_VARIANT CMAKE_CXX_COMPILER_FRONTEND_VARIANT) endif() # UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK upx_cmake_include_hook(9_finish) diff --git a/misc/cmake/functions.cmake b/misc/cmake/functions.cmake index 1e6b47dc..dc5d05ea 100644 --- a/misc/cmake/functions.cmake +++ b/misc/cmake/functions.cmake @@ -171,6 +171,18 @@ function(upx_cache_bool_vars) # ARGV endforeach() endfunction() +function(upx_platform_check_mismatch var_name_1 var_name_2) + if(DEFINED ${var_name_1} OR DEFINED ${var_name_2}) + if(NOT ",${${var_name_1}}," STREQUAL ",${${var_name_2}},") + if(UPX_CONFIG_DISABLE_WERROR) + message(WARNING "WARNING: '${var_name_1}' '${var_name_2}' mismatch") + else() + message(FATAL_ERROR "FATAL ERROR: '${var_name_1}' '${var_name_2}' mismatch") + endif() + endif() + endif() +endfunction() + #*********************************************************************** # compilation flags #*********************************************************************** diff --git a/misc/scripts/run_cmake_config.sh b/misc/scripts/run_cmake_config.sh index 3e8fa027..15b5eae3 100755 --- a/misc/scripts/run_cmake_config.sh +++ b/misc/scripts/run_cmake_config.sh @@ -4,36 +4,37 @@ set -e; set -o pipefail # Copyright (C) Markus Franz Xaver Johannes Oberhumer # assemble cmake config flags; useful for CI jobs +# also see misc/make/Makefile-extra.mk cmake_config_flags=() -add_flag() { +__add_cmake_config() { [[ -z "${!1}" ]] || cmake_config_flags+=( -D$1="${!1}" ) } # pass common CMake settings from environment to cmake for v in CMAKE_VERBOSE_MAKEFILE; do - add_flag $v + __add_cmake_config $v done # pass common CMake toolchain settings from environment to cmake for v in CMAKE_ADDR2LINE CMAKE_AR CMAKE_DLLTOOL CMAKE_LINKER CMAKE_NM CMAKE_OBJCOPY CMAKE_OBJDUMP CMAKE_RANLIB CMAKE_READELF CMAKE_STRIP CMAKE_TAPI; do - add_flag $v + __add_cmake_config $v done # pass common CMake LTO toolchain settings from environment to cmake (for use with "-flto") for v in CMAKE_C_COMPILER_AR CMAKE_C_COMPILER_RANLIB CMAKE_CXX_COMPILER_AR CMAKE_CXX_COMPILER_RANLIB; do - add_flag $v + __add_cmake_config $v done # pass common CMake cross compilation settings from environment to cmake for v in CMAKE_SYSTEM_NAME CMAKE_SYSTEM_PROCESSOR CMAKE_CROSSCOMPILING_EMULATOR; do - add_flag $v + __add_cmake_config $v done # pass UPX config options from environment to cmake; see CMakeLists.txt for v in UPX_CONFIG_DISABLE_GITREV UPX_CONFIG_DISABLE_SANITIZE UPX_CONFIG_DISABLE_WSTRICT UPX_CONFIG_DISABLE_WERROR UPX_CONFIG_DISABLE_SELF_PACK_TEST; do - add_flag $v + __add_cmake_config $v done # pass UPX extra compile options from environment to cmake; see CMakeLists.txt for v in UPX_CONFIG_EXTRA_COMPILE_OPTIONS_BZIP2 UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UCL UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UPX UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZLIB UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZSTD; do - add_flag $v + __add_cmake_config $v done exec "${CMAKE:-cmake}" $UPX_CMAKE_CONFIG_FLAGS "${cmake_config_flags[@]}" "$@" diff --git a/src/check/dt_check.cpp b/src/check/dt_check.cpp index b80c3d95..6c47409a 100644 --- a/src/check/dt_check.cpp +++ b/src/check/dt_check.cpp @@ -741,12 +741,14 @@ TEST_CASE("libc snprintf") { CHECK_EQ(strcmp(buf, "-6.0.0.0.0.0.0.0.6.ffffffffffffffff"), 0); snprintf(buf, sizeof(buf), "%d.%d.%d.%d.%d.%d.%d.%d.%d.%#jx", -7, 0, 0, 0, 0, 0, 0, 0, 7, um); CHECK_EQ(strcmp(buf, "-7.0.0.0.0.0.0.0.7.0xffffffffffffffff"), 0); - snprintf(buf, sizeof(buf), "%#x %#lx %#llx", 17u, 18ul, 19ull); - CHECK_EQ(strcmp(buf, "0x11 0x12 0x13"), 0); - snprintf(buf, sizeof(buf), "%#X %#lX %#llX", 20u, 21ul, 22ull); - CHECK_EQ(strcmp(buf, "0X14 0X15 0X16"), 0); - snprintf(buf, sizeof(buf), "%#06x %#06lx %#06llx", 23u, 24ul, 25ull); - CHECK_EQ(strcmp(buf, "0x0017 0x0018 0x0019"), 0); + snprintf(buf, sizeof(buf), "%#X %#lx %#llx", 26u, 27ul, 28ull); + CHECK_EQ(strcmp(buf, "0X1A 0x1b 0x1c"), 0); + snprintf(buf, sizeof(buf), "%#06x %#06lX %#06llx", 26u, 27ul, 28ull); + CHECK_EQ(strcmp(buf, "0x001a 0X001B 0x001c"), 0); + snprintf(buf, sizeof(buf), "%#6x %#6lx %#6llX", 26u, 27ul, 28ull); + CHECK_EQ(strcmp(buf, " 0x1a 0x1b 0X1C"), 0); + snprintf(buf, sizeof(buf), "%#-6X %#-6lx %#-6llx", 26u, 27ul, 28ull); + CHECK_EQ(strcmp(buf, "0X1A 0x1b 0x1c "), 0); } #if 0 diff --git a/src/check/dt_cxxlib.cpp b/src/check/dt_cxxlib.cpp index 8f7fb27c..c4ba68b8 100644 --- a/src/check/dt_cxxlib.cpp +++ b/src/check/dt_cxxlib.cpp @@ -131,7 +131,7 @@ TEST_CASE("libc++") { CHECK(v.end() - v.begin() == N); CHECK(&v[0] == &(*(v.begin()))); // CHECK(&v[0] + N == &(*(v.end()))); // TODO later: is this legal?? - // TODO later + // TODO later: make sure that this throws #if defined(_LIBCPP_HARDENING_MODE_DEBUG) && \ (_LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG) CHECK_THROWS((void) &v[N]); @@ -176,7 +176,7 @@ struct MyVType2 { UPX_CXX_DISABLE_ADDRESS(Self) UPX_CXX_DISABLE_NEW_DELETE(Self) }; -TEST_CASE("upx_cxx_disable") { +TEST_CASE("UPX_CXX_DISABLE_xxx") { MyType1 dummy1; MyType2 dummy2; MyVType1 vdummy1; @@ -260,7 +260,7 @@ struct Z2_X2 : public X2 { // util **************************************************************************/ -TEST_CASE("Deleter") { +TEST_CASE("upx::ObjectDeleter 1") { LE16 *o = nullptr; // object LE32 *a = nullptr; // array { @@ -275,7 +275,7 @@ TEST_CASE("Deleter") { assert(a == nullptr); } -TEST_CASE("Deleter") { +TEST_CASE("upx::ObjectDeleter 2") { constexpr size_t N = 2; BE16 *o[N]; // multiple objects BE32 *a[N]; // multiple arrays @@ -284,8 +284,10 @@ TEST_CASE("Deleter") { upx::ArrayDeleter a_deleter{a, 0}; for (size_t i = 0; i < N; i++) { o[i] = new BE16; + assert(o[i] != nullptr); o_deleter.count += 1; a[i] = New(BE32, 1 + i); + assert(a[i] != nullptr); a_deleter.count += 1; } } @@ -295,7 +297,7 @@ TEST_CASE("Deleter") { } } -TEST_CASE("ptr_static_cast") { +TEST_CASE("upx::ptr_static_cast") { // check that we don't trigger any -Wcast-align warnings using upx::ptr_static_cast; void *vp = nullptr; @@ -335,7 +337,7 @@ TEST_CASE("ptr_static_cast") { assert((ic == ptr_static_cast(ic))); } -TEST_CASE("noncopyable") { +TEST_CASE("upx::noncopyable") { struct Test : private upx::noncopyable { int v = 1; }; @@ -458,7 +460,7 @@ struct TestTriBool { }; } // namespace -TEST_CASE("TriBool") { +TEST_CASE("upx::TriBool") { using upx::TriBool, upx::tribool; static_assert(!tribool(false)); static_assert(tribool(true)); diff --git a/src/help.cpp b/src/help.cpp index 274543a5..d8ba6bbb 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -96,16 +96,18 @@ void show_usage(void) { namespace { struct PackerNames { + PackerNames() noexcept = default; + ~PackerNames() noexcept = default; struct Entry { const char *fname; const char *sname; }; - Entry names[64]; - size_t names_count; - const Options *o; - PackerNames() : names_count(0), o(nullptr) {} + static constexpr size_t MAX_NAMES = 64; + Entry names[MAX_NAMES]; + size_t names_count = 0; + const Options *o = nullptr; void add(const PackerBase *pb) { - assert_noexcept(names_count < 64); + assert_noexcept(names_count < MAX_NAMES); names[names_count].fname = pb->getFullName(o); names[names_count].sname = pb->getName(); names_count++; diff --git a/src/util/membuffer.cpp b/src/util/membuffer.cpp index 89036256..c0cdbb2f 100644 --- a/src/util/membuffer.cpp +++ b/src/util/membuffer.cpp @@ -320,12 +320,17 @@ TEST_CASE("MemBuffer global overloads") { CHECK_THROWS(set_le64(mb4, 0)); } -TEST_CASE("MemBuffer unused") { +TEST_CASE("MemBuffer unused 1") { MemBuffer mb; CHECK(mb.raw_ptr() == nullptr); CHECK(mb.raw_size_in_bytes() == 0); } +TEST_CASE("MemBuffer unused 2") { + MemBuffer mb; + (void) mb; +} + TEST_CASE("MemBuffer array access") { constexpr size_t N = 16; MemBuffer mb(N); diff --git a/src/work.cpp b/src/work.cpp index ed06250f..9bed93b2 100644 --- a/src/work.cpp +++ b/src/work.cpp @@ -29,6 +29,9 @@ // dispatch. PackMaster by itself will instantiate a concrete subclass // of class PackerBase which then does the actual work. // And see p_com.cpp for a simple executable format. +// +// This file also has the burden to deal with all those pesky low-level +// file handling issues. #define WANT_WINDOWS_LEAN_H 1 // _get_osfhandle, GetFileTime, SetFileTime #include "util/system_headers.h" @@ -325,7 +328,7 @@ void do_one_file(const char *const iname, char *const oname) may_throw { } } - // handle command - actual work is here + // handle command - actual work starts HERE PackMaster pm(&fi, opt); if (opt->cmd == CMD_COMPRESS) pm.pack(&fo);