diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f50e0824..28c280aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -207,10 +207,11 @@ jobs: fail-fast: false matrix: include: + # NOTE: Xcode updates regularly tend to break Homebrew clang/gcc; often some ld64 issue; use "xcode_version" as needed; or try "-Wl,-ld_classic" # NOTE: macos does not have "env -C"; only with brew coreutils # NOTE: macos-11 does not have "readlink -f"; only on macos >= 12 or with brew coreutils # { os: macos-11, gcc: gcc-10, gxx: g++-10, testsuite: true } # macos-11 is EOL; scheduled for removal from GitHub actions - - { os: macos-12, gcc: gcc-11, gxx: g++-11, testsuite: true } + - { os: macos-12, gcc: gcc-12, gxx: g++-12, testsuite: true } - { os: macos-13, testsuite: true } # use default Xcode-15; NOTE: gcc-12 on macos-13 does not work with Xcode-15 - { os: macos-13, gcc: gcc-12, gxx: g++-12, testsuite: true, xcode_version: 14.3.1 } # { os: macos-14, gcc: gcc-13, gxx: g++-13, testsuite: true } # gcc-13: INTERNAL ERROR in ld64 diff --git a/CMakeLists.txt b/CMakeLists.txt index 90340a25..b4b85116 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,6 +136,10 @@ upx_set_default_build_type(Release) # default is CMAKE_BUILD_TYPE=Release project(upx VERSION "${UPX_VERSION_STRING}" LANGUAGES C CXX) upx_apply_build_type() +if(DEFINED UPX_CONFIG_CMAKE_EXECUTABLE_SUFFIX) + set(CMAKE_EXECUTABLE_SUFFIX "${UPX_CONFIG_CMAKE_EXECUTABLE_SUFFIX}") +endif() + #*********************************************************************** # common compilation flags #*********************************************************************** diff --git a/misc/cmake/functions.cmake b/misc/cmake/functions.cmake index c68f153e..4107ee2e 100644 --- a/misc/cmake/functions.cmake +++ b/misc/cmake/functions.cmake @@ -365,15 +365,14 @@ endfunction() # sanitize a target; note that this may require special run-time support libs from your toolchain function(upx_sanitize_target) # ARGV - # default sanitizer for Debug builds - if(NOT DEFINED upx_sanitize_flags_debug) - set(upx_sanitize_flags_debug -fsanitize=undefined -fsanitize-undefined-trap-on-error -fstack-protector-all) + if(NOT DEFINED UPX_CONFIG_SANITIZE_FLAGS_DEBUG) + # default sanitizer for Debug builds + set(UPX_CONFIG_SANITIZE_FLAGS_DEBUG -fsanitize=undefined -fsanitize-undefined-trap-on-error -fstack-protector-all) endif() - # default sanitizer for Release builds - if(NOT DEFINED upx_sanitize_flags_release) - set(upx_sanitize_flags_release -fstack-protector) + if(NOT DEFINED UPX_CONFIG_SANITIZE_FLAGS_RELEASE) + # default sanitizer for Release builds + set(UPX_CONFIG_SANITIZE_FLAGS_RELEASE -fstack-protector) endif() - foreach(t ${ARGV}) if(UPX_CONFIG_DISABLE_SANITIZE) # no-op @@ -391,10 +390,10 @@ function(upx_sanitize_target) # ARGV # unsupported compiler; unreliable/broken sanitize implementation before gcc-8 (May 2018) message(WARNING "WARNING: ignoring SANITIZE for target '${t}'") else() - target_compile_options(${t} PRIVATE $<$:${upx_sanitize_flags_debug}>) - target_compile_options(${t} PRIVATE $<$:${upx_sanitize_flags_release}>) - target_compile_options(${t} PRIVATE $<$:${upx_sanitize_flags_release}>) - target_compile_options(${t} PRIVATE $<$:${upx_sanitize_flags_release}>) + target_compile_options(${t} PRIVATE $<$:${UPX_CONFIG_SANITIZE_FLAGS_DEBUG}>) + target_compile_options(${t} PRIVATE $<$:${UPX_CONFIG_SANITIZE_FLAGS_RELEASE}>) + target_compile_options(${t} PRIVATE $<$:${UPX_CONFIG_SANITIZE_FLAGS_RELEASE}>) + target_compile_options(${t} PRIVATE $<$:${UPX_CONFIG_SANITIZE_FLAGS_RELEASE}>) endif() endforeach() endfunction() diff --git a/misc/cmake/print_info.cmake b/misc/cmake/print_info.cmake index b252e134..beac8f03 100644 --- a/misc/cmake/print_info.cmake +++ b/misc/cmake/print_info.cmake @@ -31,13 +31,15 @@ function(upx_print_info) # ARGV upx_print_var(CMAKE_SIZEOF_VOID_P) # binutils - upx_print_var(CMAKE_EXECUTABLE_FORMAT CMAKE_AR CMAKE_RANLIB) + upx_print_var(CMAKE_EXECUTABLE_FORMAT CMAKE_EXECUTABLE_SUFFIX UPX_CONFIG_CMAKE_EXECUTABLE_SUFFIX) + upx_print_var(CMAKE_AR CMAKE_RANLIB) # compilers foreach(lang IN ITEMS ASM C CXX) upx_print_var(CMAKE_${lang}_COMPILER_LAUNCHER) upx_print_var(CMAKE_${lang}_COMPILER) upx_print_var(CMAKE_${lang}_COMPILER_ID) + upx_print_var(CMAKE_${lang}_SIMULATE_ID) upx_print_var(CMAKE_${lang}_COMPILER_VERSION) upx_print_var(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT ) upx_print_var(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID) @@ -50,6 +52,7 @@ function(upx_print_info) # ARGV upx_print_var(CMAKE_BUILD_WITH_INSTALL_RPATH) upx_print_var(CMAKE_INTERPROCEDURAL_OPTIMIZATION CMAKE_POSITION_INDEPENDENT_CODE) upx_print_var(PROPERTY_TARGET_SUPPORTS_SHARED_LIBS) + upx_print_var(UPX_CONFIG_SANITIZE_FLAGS_DEBUG UPX_CONFIG_SANITIZE_FLAGS_RELEASE) # shortcuts upx_print_var(APPLE CLANG CYGWIN GNU_FRONTEND GNUC MINGW MSVC MSVC_FRONTEND MSVC_IDE MSVC_TOOLSET_VERSION MSVC_VERSION MSYS UNIX WIN32 WIN64) diff --git a/misc/make/Makefile-extra.mk b/misc/make/Makefile-extra.mk index bc6a11c8..18f93bca 100644 --- a/misc/make/Makefile-extra.mk +++ b/misc/make/Makefile-extra.mk @@ -20,7 +20,7 @@ override ne = $(if $(subst x$1,,x$2)$(subst x$2,,x$1),1,) override tolower = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1)))))))))))))))))))))))))) override toupper = $(subst a,A,$(subst b,B,$(subst c,C,$(subst d,D,$(subst e,E,$(subst f,F,$(subst g,G,$(subst h,H,$(subst i,I,$(subst j,J,$(subst k,K,$(subst l,L,$(subst m,M,$(subst n,N,$(subst o,O,$(subst p,P,$(subst q,Q,$(subst r,R,$(subst s,S,$(subst t,T,$(subst u,U,$(subst v,V,$(subst w,W,$(subst x,X,$(subst y,Y,$(subst z,Z,$1)))))))))))))))))))))))))) -# canonicalize case of CMAKE_BUILD_TYPE to "Debug" and "Release" +# canonicalize the case of CMAKE_BUILD_TYPE to "Debug" and "Release" override cm_build_type = $(if $(call eq,$1,),$(error EMPTY-build-type),$(if $(call eq,$(call tolower,$1),debug),Debug,$(if $(call eq,$(call tolower,$1),release),Release,$(if $(call eq,$(call tolower,$1),none),None,$1)))) #*********************************************************************** diff --git a/src/bele.h b/src/bele.h index 155b7834..e581be2c 100644 --- a/src/bele.h +++ b/src/bele.h @@ -231,7 +231,7 @@ forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) noexcept { return std #elif (ACC_CC_MSC) -ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) +static_assert(sizeof(long) == 4); // _byteswap_XXX is unfortunately *not* constexpr with current MSVC forceinline bele_constexpr unsigned bswap16(unsigned v) noexcept { diff --git a/src/check/dt_check.cpp b/src/check/dt_check.cpp index 95de06eb..7000b799 100644 --- a/src/check/dt_check.cpp +++ b/src/check/dt_check.cpp @@ -210,6 +210,8 @@ typedef __PTRADDR_TYPE__ expected_ptraddr_t; static_assert(std::is_integral::value, ""); \ static_assert(std::is_signed::value == std::is_signed::value, ""); \ static_assert(std::is_unsigned::value == std::is_unsigned::value, ""); \ + static_assert(std::is_signed::value == !std::is_unsigned::value, ""); \ + static_assert(std::is_signed::value == !std::is_unsigned::value, ""); \ static_assert(sizeof(A) == sizeof(B), ""); \ static_assert(alignof(A) == alignof(B), "") @@ -226,6 +228,10 @@ ASSERT_SAME_TYPE(uintptr_t, std::uintptr_t); // true types ASSERT_SAME_TYPE(ptrdiff_t, true_ptrdiff_t); ASSERT_SAME_TYPE(size_t, true_size_t); +#if __cplusplus >= 201103L +typedef decltype(nullptr) true_nullptr_t; +static_assert(std::is_same::value, ""); +#endif // expected types #if defined(__PTRDIFF_TYPE__) @@ -880,6 +886,18 @@ void upx_compiler_sanity_check(void) noexcept { static_assert(sizeof(upx_off_t) >= 8); static_assert(sizeof(upx_off_t) >= sizeof(long long)); +// __int64 +#if defined(_MSC_VER) + { + ASSERT_SAME_TYPE(long long, __int64); + ASSERT_SAME_TYPE(unsigned long long, unsigned __int64); + typedef __int64 my_int64; + typedef unsigned __int64 my_uint64; + ASSERT_SAME_TYPE(long long, my_int64); + ASSERT_SAME_TYPE(unsigned long long, my_uint64); + } +#endif + static_assert(sizeof(BE16) == 2); static_assert(sizeof(BE32) == 4); static_assert(sizeof(BE64) == 8); diff --git a/src/packer.h b/src/packer.h index 6d921542..10ac758a 100644 --- a/src/packer.h +++ b/src/packer.h @@ -126,8 +126,8 @@ public: protected: // unpacker tests - these may throw exceptions - virtual bool testUnpackVersion(int version) const; - virtual bool testUnpackFormat(int format) const; + virtual bool testUnpackVersion(int version) const may_throw; + virtual bool testUnpackFormat(int format) const may_throw; protected: // implementation diff --git a/src/util/cxxlib.h b/src/util/cxxlib.h index 9135e7bf..9d91d7a7 100644 --- a/src/util/cxxlib.h +++ b/src/util/cxxlib.h @@ -773,8 +773,12 @@ inline void owner_free(OwningPointer(T)(&object)) noexcept { #if defined(__clang__) || __GNUC__ != 7 template inline void owner_delete(T (&array)[]) noexcept DELETED_FUNCTION; +template +inline void owner_free(T (&array)[]) noexcept DELETED_FUNCTION; #endif template inline void owner_delete(T (&array)[N]) noexcept DELETED_FUNCTION; +template +inline void owner_free(T (&array)[N]) noexcept DELETED_FUNCTION; } // namespace upx diff --git a/src/util/windows_lean.h b/src/util/windows_lean.h index f7cbe6ce..0dc558be 100644 --- a/src/util/windows_lean.h +++ b/src/util/windows_lean.h @@ -60,7 +60,7 @@ #if defined(__CYGWIN__) && defined(_WIN32) #error "unexpected _WIN32" -#undef _WIN32 +// #undef _WIN32 #endif #if defined(__CYGWIN__) && defined(_WIN64) // #error "unexpected _WIN64"