diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c7f779a37d..92efb3a048 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,6 @@ env: GIT_FETCH_JOBS: 8 NET_RETRY_COUNT: 5 DEFAULT_BUILD_VARIANT: release - ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true jobs: posix: @@ -251,9 +250,6 @@ jobs: - libc++-14-dev - libc++abi-14-dev - - toolset: clang - cxxstd: "11,14" - os: macos-12 - toolset: clang cxxstd: "20" os: macos-13 @@ -262,7 +258,11 @@ jobs: os: macos-14 runs-on: ${{matrix.os}} - container: ${{matrix.container}} + container: + image: ${{matrix.container}} + volumes: + - /node20217:/node20217:rw,rshared + - ${{ startsWith(matrix.container, 'ubuntu:1') && '/node20217:/__e/node20:ro,rshared' || ' ' }} steps: - name: Setup environment @@ -286,9 +286,13 @@ jobs: fi apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https ca-certificates make build-essential g++ $PYTHON_PACKAGE python3 perl git cmake fi + if [[ "${{matrix.container}}" == "ubuntu:1"* ]]; then + # Node 20 doesn't work with Ubuntu 16/18 glibc: https://github.com/actions/checkout/issues/1590 + curl -sL https://archives.boost.io/misc/node/node-v20.9.0-linux-x64-glibc-217.tar.xz | tar -xJ --strip-components 1 -C /node20217 + fi fi git config --global pack.threads 0 - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages if: matrix.install diff --git a/include/boost/test/data/size.hpp b/include/boost/test/data/size.hpp index 3e9ba96795..fd10f9107f 100644 --- a/include/boost/test/data/size.hpp +++ b/include/boost/test/data/size.hpp @@ -17,6 +17,7 @@ // STL #include +#include #include @@ -30,7 +31,7 @@ namespace data { // ************** size_t ************** // // ************************************************************************** // -//! Utility for handling the size of a datasets +//! Utility for handling the size of a dataset class size_t { struct dummy { void nonnull() {} }; typedef void (dummy::*safe_bool)(); diff --git a/include/boost/test/impl/execution_monitor.ipp b/include/boost/test/impl/execution_monitor.ipp index 848670b80c..8d7500afd2 100644 --- a/include/boost/test/impl/execution_monitor.ipp +++ b/include/boost/test/impl/execution_monitor.ipp @@ -195,8 +195,8 @@ namespace { void _set_se_translator( void* ) {} } #endif #if (!defined(BOOST_MSSTL_VERSION) || (BOOST_MSSTL_VERSION >= 120)) && (!defined(__GLIBC__) || ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2)))) -// glibc 2.2 - 2.17 required __STDC_FORMAT_MACROS to be defined for use of PRIxPTR -# if defined(__GLIBC__) && !((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 18))) +// glibc 2.2 - 2.17 required __STDC_FORMAT_MACROS to be defined for use of PRIxPTR, as well as some versions of macOS. +# if (defined(__GLIBC__) && !((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 18)))) || defined(__APPLE__) # ifndef __STDC_FORMAT_MACROS # define __STDC_FORMAT_MACROS 1 # define BOOST_TEST_DEFINED_STDC_FORMAT_MACROS @@ -207,7 +207,18 @@ namespace { void _set_se_translator( void* ) {} } # ifdef BOOST_TEST_DEFINED_STDC_FORMAT_MACROS # undef __STDC_FORMAT_MACROS # endif -#else +#endif +// If any modern toolchain did not pick up a definition from above it will here +#ifndef BOOST_TEST_PRIxPTR +# ifdef __has_include +# if __has_include() +# include +# define BOOST_TEST_PRIxPTR PRIxPTR +# endif +# endif +#endif +// Last resort +#ifndef BOOST_TEST_PRIxPTR # define BOOST_TEST_PRIxPTR "08lx" #endif diff --git a/include/boost/test/impl/test_tree.ipp b/include/boost/test/impl/test_tree.ipp index f17a63567a..9654718402 100644 --- a/include/boost/test/impl/test_tree.ipp +++ b/include/boost/test/impl/test_tree.ipp @@ -501,16 +501,16 @@ auto_test_unit_registrar::auto_test_unit_registrar( const_string ts_name, const_ //____________________________________________________________________________// -auto_test_unit_registrar::auto_test_unit_registrar( test_unit_generator const& tc_gen, decorator::collector_t& decorators ) +auto_test_unit_registrar::auto_test_unit_registrar( test_unit_generator const& tc_generator, decorator::collector_t& decorators ) { - framework::current_auto_test_suite().add( tc_gen, decorators ); + framework::current_auto_test_suite().add( tc_generator, decorators ); } //____________________________________________________________________________// -auto_test_unit_registrar::auto_test_unit_registrar( boost::shared_ptr tc_gen, decorator::collector_t& decorators ) +auto_test_unit_registrar::auto_test_unit_registrar( boost::shared_ptr tc_generator, decorator::collector_t& decorators ) { - framework::current_auto_test_suite().add( tc_gen, decorators ); + framework::current_auto_test_suite().add( tc_generator, decorators ); } diff --git a/include/boost/test/tree/auto_registration.hpp b/include/boost/test/tree/auto_registration.hpp index e9510be292..39f4bc4e27 100644 --- a/include/boost/test/tree/auto_registration.hpp +++ b/include/boost/test/tree/auto_registration.hpp @@ -39,8 +39,8 @@ struct BOOST_TEST_DECL auto_test_unit_registrar { // Constructors auto_test_unit_registrar( test_case* tc, decorator::collector_t& decorators, counter_t exp_fail = 0 ); explicit auto_test_unit_registrar( const_string ts_name, const_string ts_file, std::size_t ts_line, decorator::collector_t& decorators ); - explicit auto_test_unit_registrar( test_unit_generator const& tc_gen, decorator::collector_t& decorators ); - explicit auto_test_unit_registrar( boost::shared_ptr tc_gen, decorator::collector_t& decorators ); + explicit auto_test_unit_registrar( test_unit_generator const& tc_generator, decorator::collector_t& decorators ); + explicit auto_test_unit_registrar( boost::shared_ptr tc_generator, decorator::collector_t& decorators ); explicit auto_test_unit_registrar( int ); }; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index ddf6ad5ac3..20ae7c7ea9 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -150,6 +150,7 @@ test-suite "framework-ts" [ boost.test-self-test run : framework-ts : decorators-datatestcase-test : : : : : : $(requirements_datasets) ] [ compile-fail framework-ts/master-test-suite-non-copyable-test.cpp ../build//included ] [ boost.test-self-test run : framework-ts : log-count-skipped-test : included : baseline-outputs/log-count-skipped-tests.pattern ] + [ boost.test-self-test run : framework-ts : dataset-size ] # ticket 13371: "Use-after-free with --log_sink=file" # this single check is not enough as we should check for various command line options: we make extensive diff --git a/test/framework-ts/dataset-size.cpp b/test/framework-ts/dataset-size.cpp new file mode 100644 index 0000000000..647ec58494 --- /dev/null +++ b/test/framework-ts/dataset-size.cpp @@ -0,0 +1,251 @@ +// (C) Copyright Alexander Grund 2025. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_TEST_MODULE dataset size class +#include + +#include +#include + +namespace data = boost::unit_test::data; + +BOOST_AUTO_TEST_CASE(test_constructor) +{ + data::size_t sz0; + BOOST_TEST(!sz0.is_inf()); + BOOST_TEST(sz0.value() == 0u); + BOOST_TEST(!sz0); + + data::size_t sz2 = sz0; + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == 0u); + BOOST_TEST(!sz2); + + data::size_t sz1(42); + BOOST_TEST(!sz1.is_inf()); + BOOST_TEST(sz1.value() == 42u); + BOOST_TEST(!!sz1); + + data::size_t sz3 = sz1; + BOOST_TEST(!sz3.is_inf()); + BOOST_TEST(sz3.value() == 42u); + BOOST_TEST(!!sz3); + + data::size_t sz4(true); + BOOST_TEST(sz4.is_inf()); + BOOST_TEST(sz4.value() == 0u); + BOOST_TEST(!!sz4); + + data::size_t sz5(false); + BOOST_TEST(sz5.is_inf()); + BOOST_TEST(sz5.value() == 0u); + BOOST_TEST(!!sz5); + + sz2 = sz5; + BOOST_TEST(sz2.is_inf()); + BOOST_TEST(sz2.value() == 0u); + BOOST_TEST(!!sz2); + + sz2 = sz1; + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == 42u); + BOOST_TEST(!!sz2); +} + +BOOST_AUTO_TEST_CASE(test_unary_ops) +{ + data::size_t sz(100); + + data::size_t sz2 = ++sz; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 101u); + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == 101u); + + sz2 = sz++; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 102u); + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == 101u); + + sz2 = --sz; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 101u); + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == 101u); + + sz2 = sz--; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 100u); + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == 101u); + + // Over- and underflow + BOOST_CONSTEXPR_OR_CONST std::size_t maxVal = (std::numeric_limits::max)(); + sz = maxVal; + sz2 = ++sz; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == 0u); + + sz = maxVal; + sz2 = sz++; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 0); + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == maxVal); + + sz = 0; + sz2 = --sz; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == maxVal); + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == maxVal); + + sz = 0; + sz2 = sz--; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == maxVal); + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == 0u); + + //____________________________________________________________________________// + sz = data::BOOST_TEST_DS_INFINITE_SIZE; + sz2 = ++sz; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + BOOST_TEST(sz2.is_inf()); + BOOST_TEST(sz2.value() == 0u); + + sz2 = sz++; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + BOOST_TEST(sz2.is_inf()); + BOOST_TEST(sz2.value() == 0u); + + sz2 = --sz; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + BOOST_TEST(sz2.is_inf()); + BOOST_TEST(sz2.value() == 0u); + + sz2 = sz--; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + BOOST_TEST(sz2.is_inf()); + BOOST_TEST(sz2.value() == 0u); +} + +BOOST_AUTO_TEST_CASE(test_binary_inc) +{ + data::size_t sz(100); + + sz += 5; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 105u); + + sz += data::size_t(5); + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 110u); + + sz += data::BOOST_TEST_DS_INFINITE_SIZE; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + //____________________________________________________________________________// + sz = data::BOOST_TEST_DS_INFINITE_SIZE; + + sz += 5; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + sz += data::size_t(5); + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + sz += data::BOOST_TEST_DS_INFINITE_SIZE; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + //____________________________________________________________________________// + data::size_t sz2(100); + + sz = sz2 + 5; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 105u); + + sz = sz2 + data::size_t(5); + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 105u); + + sz = sz2 + data::BOOST_TEST_DS_INFINITE_SIZE; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + //____________________________________________________________________________// + sz2 = data::BOOST_TEST_DS_INFINITE_SIZE; + + sz = sz2 + 5; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + sz = sz2 + data::size_t(5); + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + sz = sz2 + data::BOOST_TEST_DS_INFINITE_SIZE; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); +} + +BOOST_AUTO_TEST_CASE(test_binary_dec) +{ + data::size_t sz(100); + + sz -= 5; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 95u); + + sz -= data::size_t(5); + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 90u); + + sz -= data::BOOST_TEST_DS_INFINITE_SIZE; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 90u); + + //____________________________________________________________________________// + sz = data::BOOST_TEST_DS_INFINITE_SIZE; + + sz -= 5; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + sz -= data::size_t(5); + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + sz -= data::BOOST_TEST_DS_INFINITE_SIZE; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + BOOST_CONSTEXPR_OR_CONST std::size_t maxVal = (std::numeric_limits::max)(); + // Underflow is avoided for data::size_t values + sz = 1; + sz -= 5; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == maxVal - 5u + 2u); + + sz = 1; + sz -= data::size_t(5); + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + sz = 1; + sz -= data::BOOST_TEST_DS_INFINITE_SIZE; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 1u); +} \ No newline at end of file