diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d285eab..e861c042 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,7 @@ env: CTEST_OUTPUT_ON_FAILURE: 'ON' DEBIAN_FRONTEND: noninteractive UPX_CMAKE_BUILD_FLAGS: --verbose + UPX_CMAKE_CONFIG_FLAGS: -Wdev --warn-uninitialized # 2023-11-08 ZIG_DIST_VERSION: 0.12.0-dev.1502+b3462b7ce diff --git a/.github/workflows/weekly-ci-bs-cmake-windows-make.yml b/.github/workflows/weekly-ci-bs-cmake-windows-make.yml index dada70bb..31640148 100644 --- a/.github/workflows/weekly-ci-bs-cmake-windows-make.yml +++ b/.github/workflows/weekly-ci-bs-cmake-windows-make.yml @@ -12,7 +12,7 @@ env: DEBIAN_FRONTEND: noninteractive UPX_CONFIG_EXPECT_THREADS: 'ON' UPX_CMAKE_BUILD_FLAGS: --verbose - UPX_CMAKE_CONFIG_FLAGS: -G "Unix Makefiles" + UPX_CMAKE_CONFIG_FLAGS: -G "Unix Makefiles" -Wdev --warn-uninitialized jobs: job-cmake-windows-make: # uses cmake + make diff --git a/.github/workflows/weekly-ci-bs-cmake-windows-ninja.yml b/.github/workflows/weekly-ci-bs-cmake-windows-ninja.yml index 0a5de7b1..76353c3d 100644 --- a/.github/workflows/weekly-ci-bs-cmake-windows-ninja.yml +++ b/.github/workflows/weekly-ci-bs-cmake-windows-ninja.yml @@ -12,7 +12,7 @@ env: DEBIAN_FRONTEND: noninteractive UPX_CONFIG_EXPECT_THREADS: 'ON' UPX_CMAKE_BUILD_FLAGS: --verbose - UPX_CMAKE_CONFIG_FLAGS: -G Ninja + UPX_CMAKE_CONFIG_FLAGS: -G Ninja -Wdev --warn-uninitialized jobs: job-cmake-windows-ninja: # uses cmake + ninja diff --git a/.github/workflows/weekly-ci-cc-alpine-linux.yml b/.github/workflows/weekly-ci-cc-alpine-linux.yml index 6578a7e7..206def02 100644 --- a/.github/workflows/weekly-ci-cc-alpine-linux.yml +++ b/.github/workflows/weekly-ci-cc-alpine-linux.yml @@ -19,6 +19,7 @@ env: CMAKE_VERBOSE_MAKEFILE: 'ON' CTEST_OUTPUT_ON_FAILURE: 'ON' DEBIAN_FRONTEND: noninteractive + UPX_CMAKE_CONFIG_FLAGS: -Wdev --warn-uninitialized UPX_TESTSUITE_LEVEL: 4 jobs: diff --git a/.github/workflows/weekly-ci-cc-alpine-mingw.yml b/.github/workflows/weekly-ci-cc-alpine-mingw.yml index 2224c0e2..17f6af56 100644 --- a/.github/workflows/weekly-ci-cc-alpine-mingw.yml +++ b/.github/workflows/weekly-ci-cc-alpine-mingw.yml @@ -10,6 +10,7 @@ env: CMAKE_VERBOSE_MAKEFILE: 'ON' CTEST_OUTPUT_ON_FAILURE: 'ON' DEBIAN_FRONTEND: noninteractive + UPX_CMAKE_CONFIG_FLAGS: -Wdev --warn-uninitialized UPX_CONFIG_EXPECT_THREADS: 'ON' jobs: diff --git a/.github/workflows/weekly-ci-cc-llvm-mingw.yml b/.github/workflows/weekly-ci-cc-llvm-mingw.yml index 52221fc2..b3fd3a65 100644 --- a/.github/workflows/weekly-ci-cc-llvm-mingw.yml +++ b/.github/workflows/weekly-ci-cc-llvm-mingw.yml @@ -12,6 +12,7 @@ env: CMAKE_VERBOSE_MAKEFILE: 'ON' CTEST_OUTPUT_ON_FAILURE: 'ON' DEBIAN_FRONTEND: noninteractive + UPX_CMAKE_CONFIG_FLAGS: -Wdev --warn-uninitialized UPX_CONFIG_EXPECT_THREADS: 'ON' jobs: diff --git a/misc/scripts/build_upx_by_hand.sh b/misc/scripts/build_upx_by_hand.sh index e99db694..9bb29176 100755 --- a/misc/scripts/build_upx_by_hand.sh +++ b/misc/scripts/build_upx_by_hand.sh @@ -85,7 +85,7 @@ check_submodule() { # create and enter build directory; updates global $rel_top_srcdir run "+" cd "$rel_top_srcdir" || exit 1 rel_top_srcdir=. - echo "#==== build $1 =====" + echo "#===== build $1 =====" run "+" mkdir "build/by-hand/$1" run "+" cd "build/by-hand/$1" || exit 1 rel_top_srcdir=../../.. @@ -128,13 +128,13 @@ if check_submodule zstd; then fi run "+" cd "$rel_top_srcdir" || exit 1 rel_top_srcdir=. -echo "#==== build UPX =====" +echo "#===== build UPX =====" run "+" cd "build/by-hand" || exit 1 rel_top_srcdir=../.. for f in "$rel_top_srcdir"/src/*.cpp "$rel_top_srcdir"/src/*/*.cpp; do run "CXX $f" $CXX -I"$rel_top_srcdir"/vendor $upx_submodule_defs -c "$f" done -# echo "#==== link UPX =====" +# echo "#===== link UPX =====" test "x$obj_suffix" = "x" && obj_suffix=.o if test "x$AR" = "x"; then # link without using $AR diff --git a/src/bele_policy.h b/src/bele_policy.h index f147be4c..2aadad27 100644 --- a/src/bele_policy.h +++ b/src/bele_policy.h @@ -84,7 +84,7 @@ private: AbstractPolicy(AbstractPolicy &&) noexcept DELETED_FUNCTION; AbstractPolicy &operator=(AbstractPolicy &&) noexcept DELETED_FUNCTION; // disable dynamic allocation - ACC_CXX_DISABLE_NEW_DELETE + UPX_CXX_DISABLE_NEW_DELETE }; #endif @@ -152,7 +152,7 @@ private: BEPolicy(BEPolicy &&) noexcept DELETED_FUNCTION; BEPolicy &operator=(BEPolicy &&) noexcept DELETED_FUNCTION; // disable dynamic allocation - ACC_CXX_DISABLE_NEW_DELETE + UPX_CXX_DISABLE_NEW_DELETE }; struct LEPolicy @@ -214,7 +214,7 @@ private: LEPolicy(LEPolicy &&) noexcept DELETED_FUNCTION; LEPolicy &operator=(LEPolicy &&) noexcept DELETED_FUNCTION; // disable dynamic allocation - ACC_CXX_DISABLE_NEW_DELETE + UPX_CXX_DISABLE_NEW_DELETE }; // Native Endianness policy (aka host policy) diff --git a/src/check/dt_cxxlib.cpp b/src/check/dt_cxxlib.cpp index faea0ab3..3e71f7c3 100644 --- a/src/check/dt_cxxlib.cpp +++ b/src/check/dt_cxxlib.cpp @@ -97,6 +97,78 @@ ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_gt("abc", "abz")) ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_ge("abc", "abz")) ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_le("abc", "abz")) +/************************************************************************* +// UPX_CXX_DISABLE_NEW_DELETE +**************************************************************************/ + +namespace test_disable_new_delete { + +struct A1 { + int a; +}; +struct A2 { + int a; + UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL +}; +struct B1_A1 : public A1 { + int b; +}; +struct B1_A2 : public A2 { + int b; +}; +struct B2_A1 : public A1 { + int b; + UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL +}; +struct B2_A2 : public A2 { + int b; + UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL +}; + +struct X1 { + virtual ~X1() noexcept {} + int x; +}; +struct X2 { + virtual ~X2() noexcept {} + int x; + UPX_CXX_DISABLE_NEW_DELETE +}; +struct Y1_X1 : public X1 { + int y; +}; +struct Y1_X2 : public X2 { + int y; +}; +struct Y2_X1 : public X1 { + int y; + UPX_CXX_DISABLE_NEW_DELETE +}; +struct Y2_X2 : public X2 { + int y; + UPX_CXX_DISABLE_NEW_DELETE +}; +struct Z1_X1 : public X1 { + virtual ~Z1_X1() noexcept {} + int z; +}; +struct Z1_X2 : public X2 { + virtual ~Z1_X2() noexcept {} + int z; +}; +struct Z2_X1 : public X1 { + virtual ~Z2_X1() noexcept {} + int z; + UPX_CXX_DISABLE_NEW_DELETE +}; +struct Z2_X2 : public X2 { + virtual ~Z2_X2() noexcept {} + int z; + UPX_CXX_DISABLE_NEW_DELETE +}; + +} // namespace test_disable_new_delete + /************************************************************************* // util **************************************************************************/ diff --git a/src/except.h b/src/except.h index 3669bb89..0f9b666b 100644 --- a/src/except.h +++ b/src/except.h @@ -61,7 +61,7 @@ private: Throwable(Throwable &&) noexcept DELETED_FUNCTION; Throwable &operator=(Throwable &&) noexcept DELETED_FUNCTION; // disable dynamic allocation => force throwing by value - ACC_CXX_DISABLE_NEW_DELETE + UPX_CXX_DISABLE_NEW_DELETE // 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] Throwable *operator&() const noexcept DELETED_FUNCTION; diff --git a/src/util/cxxlib.h b/src/util/cxxlib.h index 416de3fd..bde44147 100644 --- a/src/util/cxxlib.h +++ b/src/util/cxxlib.h @@ -26,11 +26,63 @@ #pragma once -// #include +// #include +// #include // #include namespace upx { +/************************************************************************* +// core +**************************************************************************/ + +// fun with C++: disable common "new" and ALL "delete" operators +#define UPX_CXX_DISABLE_NEW_DELETE_COMMON__ \ +private: \ + /* common allocation functions (4) */ \ + 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 placement deallocation functions (4) */ \ + static void operator delete(void *, const std::nothrow_t &) noexcept = delete; \ + static void operator delete[](void *, const std::nothrow_t &) noexcept = delete; \ + static void operator delete(void *, std::align_val_t, const std::nothrow_t &) noexcept = \ + delete; \ + static void operator delete[](void *, std::align_val_t, const std::nothrow_t &) noexcept = \ + delete; \ + /* non-allocating placement deallocation functions (2) */ \ + static void operator delete(void *, void *) noexcept = delete; \ + static void operator delete[](void *, void *) noexcept = delete; + +// for classes with virtual methods +#define UPX_CXX_DISABLE_NEW_DELETE \ + UPX_CXX_DISABLE_NEW_DELETE_COMMON__ \ + /* replaceable usual deallocation functions (8) */ \ +protected: \ + static void operator delete(void *) noexcept {} \ + static void operator delete[](void *) noexcept = delete; \ + static void operator delete(void *, std::align_val_t) {} \ + static void operator delete[](void *, std::align_val_t) noexcept = delete; \ + static void operator delete(void *, std::size_t) {} \ + static void operator delete[](void *, std::size_t) noexcept = delete; \ + static void operator delete(void *, std::size_t, std::align_val_t) {} \ + static void operator delete[](void *, std::size_t, std::align_val_t) noexcept = delete; \ +private: + +// for classes WITHOUT any virtual methods +#define UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL \ + UPX_CXX_DISABLE_NEW_DELETE_COMMON__ \ + /* replaceable usual deallocation functions (8) */ \ + static void operator delete(void *) noexcept = delete; \ + static void operator delete[](void *) noexcept = delete; \ + static void operator delete(void *, std::align_val_t) = delete; \ + static void operator delete[](void *, std::align_val_t) noexcept = delete; \ + static void operator delete(void *, std::size_t) = delete; \ + static void operator delete[](void *, std::size_t) noexcept = delete; \ + static void operator delete(void *, std::size_t, std::align_val_t) = delete; \ + static void operator delete[](void *, std::size_t, std::align_val_t) noexcept = delete; + /************************************************************************* // type_traits **************************************************************************/ @@ -162,7 +214,8 @@ struct TriBool final { #endif private: - value_type value = False; // the actual value of this type + value_type value = False; // the actual value of this type + UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL // UPX convention }; typedef TriBool<> tribool; @@ -261,31 +314,7 @@ private: pointer ptr; reference operator[](std::ptrdiff_t) noexcept = delete; const_reference operator[](std::ptrdiff_t) const noexcept = delete; -#if 0 // fun with C++ - // disable common "new" and ALL "delete" operators - 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; - static void operator delete(void *, std::align_val_t) noexcept = delete; - static void operator delete[](void *, std::align_val_t) noexcept = delete; - static void operator delete(void *, std::size_t) noexcept = delete; - static void operator delete[](void *, std::size_t) noexcept = delete; - static void operator delete(void *, std::size_t, std::align_val_t) noexcept = delete; - static void operator delete[](void *, std::size_t, std::align_val_t) noexcept = delete; - // replaceable placement deallocation functions (4) - static void operator delete(void *, const std::nothrow_t &) noexcept = delete; - static void operator delete[](void *, const std::nothrow_t &) noexcept = delete; - static void operator delete(void *, std::align_val_t, const std::nothrow_t &) noexcept = delete; - static void operator delete[](void *, std::align_val_t, - const std::nothrow_t &) noexcept = delete; - // non-allocating placement deallocation functions (2) - static void operator delete(void *, void *) noexcept = delete; - static void operator delete[](void *, void *) noexcept = delete; -#endif + UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL // UPX convention }; // must overload mem_clear() template diff --git a/src/util/membuffer.h b/src/util/membuffer.h index be009f9a..01a21560 100644 --- a/src/util/membuffer.h +++ b/src/util/membuffer.h @@ -217,7 +217,7 @@ private: MemBuffer &operator=(MemBuffer &&) noexcept DELETED_FUNCTION; #endif // disable dynamic allocation - ACC_CXX_DISABLE_NEW_DELETE + UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL }; /* vim:set ts=4 sw=4 et: */