From b5373dadca40b7edc8570cf9470b9b1cb1934d40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Wed, 10 Apr 2024 12:05:46 +0200 Subject: [PATCH] v3.5.4 --- CMakeLists.txt | 2 +- docs/release-notes.md | 24 ++++ extras/catch_amalgamated.cpp | 22 ++-- extras/catch_amalgamated.hpp | 180 +++++++++++++++------------- meson.build | 2 +- src/catch2/catch_version.cpp | 2 +- src/catch2/catch_version_macros.hpp | 2 +- 7 files changed, 137 insertions(+), 97 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ce225c0e..7c3e855a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,7 +33,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) endif() project(Catch2 - VERSION 3.5.3 # CML version placeholder, don't delete + VERSION 3.5.4 # CML version placeholder, don't delete LANGUAGES CXX # HOMEPAGE_URL is not supported until CMake version 3.12, which # we do not target yet. diff --git a/docs/release-notes.md b/docs/release-notes.md index b462b01f..87cec24b 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -2,6 +2,7 @@ # Release notes **Contents**
+[3.5.4](#354)
[3.5.3](#353)
[3.5.2](#352)
[3.5.1](#351)
@@ -61,6 +62,29 @@ [Even Older versions](#even-older-versions)
+## 3.5.4 + +### Fixes +* Fixed potential compilation error when asked to generate random integers whose type did not match `std::(u)int*_t`. + * This manifested itself when generating random `size_t`s on MacOS +* Added missing outlined destructor causing `Wdelete-incomplete` when compiling against libstdc++ in C++23 mode (#2852) +* Fixed regression where decomposing assertion with const instance of `std::foo_ordering` would not compile + +### Improvements +* Reintroduced support for GCC 5 and 6 (#2836) + * As with VS2017, if they start causing trouble again, they will be dropped again. +* Added workaround for targetting newest MacOS (Sonoma) using GCC (#2837, #2839) +* `CATCH_CONFIG_DEFAULT_REPORTER` can now be an arbitrary reporter spec + * Previously it could only be a plain reporter name, so it was impossible to compile in custom arguments to the reporter. +* Improved performance of generating 64bit random integers by 20+% + +### Miscellaneous +* Significantly improved Conan in-tree recipe (#2831) +* `DL_PATHS` in `catch_discover_tests` now supports multiple arguments (#2852, #2736) +* Fixed preprocessor logic for checking whether we expect reproducible floating point results in tests. +* Improved the floating point tests structure to avoid `Wunused` when the reproducibility tests are disabled (#2845) + + ## 3.5.3 ### Fixes diff --git a/extras/catch_amalgamated.cpp b/extras/catch_amalgamated.cpp index c3fbc061..6aa67884 100644 --- a/extras/catch_amalgamated.cpp +++ b/extras/catch_amalgamated.cpp @@ -6,8 +6,8 @@ // SPDX-License-Identifier: BSL-1.0 -// Catch v3.5.3 -// Generated: 2024-03-01 22:05:56.038084 +// Catch v3.5.4 +// Generated: 2024-04-10 12:03:46.281848 // ---------------------------------------------------------- // This file is an amalgamation of multiple different files. // You probably shouldn't edit it directly. @@ -187,7 +187,7 @@ namespace Catch { double const* last, Estimator& estimator ) { auto n = static_cast( last - first ); - std::uniform_int_distribution dist( 0, n - 1 ); + Catch::uniform_integer_distribution dist( 0, n - 1 ); sample out; out.reserve( resamples ); @@ -807,14 +807,16 @@ namespace Catch { // Insert the default reporter if user hasn't asked for a specific one if ( m_data.reporterSpecifications.empty() ) { - m_data.reporterSpecifications.push_back( { #if defined( CATCH_CONFIG_DEFAULT_REPORTER ) - CATCH_CONFIG_DEFAULT_REPORTER, + const auto default_spec = CATCH_CONFIG_DEFAULT_REPORTER; #else - "console", + const auto default_spec = "console"; #endif - {}, {}, {} - } ); + auto parsed = parseReporterSpec(default_spec); + CATCH_ENFORCE( parsed, + "Cannot parse the provided default reporter spec: '" + << default_spec << '\'' ); + m_data.reporterSpecifications.push_back( std::move( *parsed ) ); } if ( enableBazelEnvSupport() ) { @@ -2271,7 +2273,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 3, 5, 3, "", 0 ); + static Version version( 3, 5, 4, "", 0 ); return version; } @@ -6601,6 +6603,8 @@ namespace Catch { return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config ); } + TestRegistry::~TestRegistry() = default; + void TestRegistry::registerTest(Detail::unique_ptr testInfo, Detail::unique_ptr testInvoker) { m_handles.emplace_back(testInfo.get(), testInvoker.get()); m_viewed_test_infos.push_back(testInfo.get()); diff --git a/extras/catch_amalgamated.hpp b/extras/catch_amalgamated.hpp index e5754314..7e75a5d1 100644 --- a/extras/catch_amalgamated.hpp +++ b/extras/catch_amalgamated.hpp @@ -6,8 +6,8 @@ // SPDX-License-Identifier: BSL-1.0 -// Catch v3.5.3 -// Generated: 2024-03-01 22:05:55.031514 +// Catch v3.5.4 +// Generated: 2024-04-10 12:03:45.785902 // ---------------------------------------------------------- // This file is an amalgamation of multiple different files. // You probably shouldn't edit it directly. @@ -87,6 +87,9 @@ // See e.g.: // https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html #ifdef __APPLE__ +# ifndef __has_extension +# define __has_extension(x) 0 +# endif # include # if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) @@ -5254,6 +5257,12 @@ namespace Detail { namespace Catch { + namespace Detail { + // This was added in C++20, but we require only C++14 for now. + template + using RemoveCVRef_t = std::remove_cv_t>; + } + // Note: There is nothing that stops us from extending this, // e.g. to `std::is_scalar`, but the more encompassing // traits are usually also more expensive. For now we @@ -5293,14 +5302,13 @@ namespace Catch { ITransientExpression(ITransientExpression const&) = default; ITransientExpression& operator=(ITransientExpression const&) = default; - // We don't actually need a virtual destructor, but many static analysers - // complain if it's not here :-( - virtual ~ITransientExpression() = default; - friend std::ostream& operator<<(std::ostream& out, ITransientExpression const& expr) { expr.streamReconstructedExpression(out); return out; } + + protected: + ~ITransientExpression() = default; }; void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ); @@ -5406,17 +5414,17 @@ namespace Catch { #define CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( id, op ) \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction, \ Detail::negation>>>::value, \ + Detail::RemoveCVRef_t>>>::value, \ BinaryExpr> { \ return { \ static_cast( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \ } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction, \ capture_by_value>::value, \ BinaryExpr> { \ @@ -5425,7 +5433,7 @@ namespace Catch { } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction< \ Detail::negation>, \ Detail::is_eq_0_comparable, \ @@ -5439,7 +5447,7 @@ namespace Catch { } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction< \ Detail::negation>, \ Detail::is_eq_0_comparable, \ @@ -5460,17 +5468,17 @@ namespace Catch { #define CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( id, op ) \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction, \ Detail::negation>>>::value, \ + Detail::RemoveCVRef_t>>>::value, \ BinaryExpr> { \ return { \ static_cast( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \ } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction, \ capture_by_value>::value, \ BinaryExpr> { \ @@ -5479,7 +5487,7 @@ namespace Catch { } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction< \ Detail::negation>, \ Detail::is_##id##_0_comparable, \ @@ -5491,7 +5499,7 @@ namespace Catch { } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction< \ Detail::negation>, \ Detail::is_##id##_0_comparable, \ @@ -5512,16 +5520,16 @@ namespace Catch { #define CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR( op ) \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \ - ->std::enable_if_t< \ - !capture_by_value>::value, \ + -> std::enable_if_t< \ + !capture_by_value>::value, \ BinaryExpr> { \ return { \ static_cast( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \ } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t::value, \ - BinaryExpr> { \ + -> std::enable_if_t::value, \ + BinaryExpr> { \ return { \ static_cast( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \ } @@ -5553,8 +5561,7 @@ namespace Catch { struct Decomposer { template >::value, + std::enable_if_t>::value, int> = 0> constexpr friend auto operator <= ( Decomposer &&, T && lhs ) -> ExprLhs { return ExprLhs{ lhs }; @@ -7263,7 +7270,7 @@ namespace Catch { #define CATCH_VERSION_MAJOR 3 #define CATCH_VERSION_MINOR 5 -#define CATCH_VERSION_PATCH 3 +#define CATCH_VERSION_PATCH 4 #endif // CATCH_VERSION_MACROS_HPP_INCLUDED @@ -7935,6 +7942,32 @@ namespace Catch { #include #include +// Note: We use the usual enable-disable-autodetect dance here even though +// we do not support these in CMake configuration options (yet?). +// It is highly unlikely that we will need to make these actually +// user-configurable, but this will make it simpler if weend up needing +// it, and it provides an escape hatch to the users who need it. +#if defined( __SIZEOF_INT128__ ) +# define CATCH_CONFIG_INTERNAL_UINT128 +#elif defined( _MSC_VER ) && ( defined( _WIN64 ) || defined( _M_ARM64 ) ) +# define CATCH_CONFIG_INTERNAL_MSVC_UMUL128 +#endif + +#if defined( CATCH_CONFIG_INTERNAL_UINT128 ) && \ + !defined( CATCH_CONFIG_NO_UINT128 ) && \ + !defined( CATCH_CONFIG_UINT128 ) +#define CATCH_CONFIG_UINT128 +#endif + +#if defined( CATCH_CONFIG_INTERNAL_MSVC_UMUL128 ) && \ + !defined( CATCH_CONFIG_NO_MSVC_UMUL128 ) && \ + !defined( CATCH_CONFIG_MSVC_UMUL128 ) +# define CATCH_CONFIG_MSVC_UMUL128 +# include +# pragma intrinsic( _umul128 ) +#endif + + namespace Catch { namespace Detail { @@ -7967,59 +8000,52 @@ namespace Catch { } }; - // Returns 128 bit result of multiplying lhs and rhs + /** + * Returns 128 bit result of lhs * rhs using portable C++ code + * + * This implementation is almost twice as fast as naive long multiplication, + * and unlike intrinsic-based approach, it supports constexpr evaluation. + */ constexpr ExtendedMultResult - extendedMult( std::uint64_t lhs, std::uint64_t rhs ) { - // We use the simple long multiplication approach for - // correctness, we can use platform specific builtins - // for performance later. - - // Split the lhs and rhs into two 32bit "digits", so that we can - // do 64 bit arithmetic to handle carry bits. - // 32b 32b 32b 32b - // lhs L1 L2 - // * rhs R1 R2 - // ------------------------ - // | R2 * L2 | - // | R2 * L1 | - // | R1 * L2 | - // | R1 * L1 | - // ------------------------- - // | a | b | c | d | - + extendedMultPortable(std::uint64_t lhs, std::uint64_t rhs) { #define CarryBits( x ) ( x >> 32 ) #define Digits( x ) ( x & 0xFF'FF'FF'FF ) + std::uint64_t lhs_low = Digits( lhs ); + std::uint64_t rhs_low = Digits( rhs ); + std::uint64_t low_low = ( lhs_low * rhs_low ); + std::uint64_t high_high = CarryBits( lhs ) * CarryBits( rhs ); - auto r2l2 = Digits( rhs ) * Digits( lhs ); - auto r2l1 = Digits( rhs ) * CarryBits( lhs ); - auto r1l2 = CarryBits( rhs ) * Digits( lhs ); - auto r1l1 = CarryBits( rhs ) * CarryBits( lhs ); - - // Sum to columns first - auto d = Digits( r2l2 ); - auto c = CarryBits( r2l2 ) + Digits( r2l1 ) + Digits( r1l2 ); - auto b = CarryBits( r2l1 ) + CarryBits( r1l2 ) + Digits( r1l1 ); - auto a = CarryBits( r1l1 ); - - // Propagate carries between columns - c += CarryBits( d ); - b += CarryBits( c ); - a += CarryBits( b ); - - // Remove the used carries - c = Digits( c ); - b = Digits( b ); - a = Digits( a ); + // We add in carry bits from low-low already + std::uint64_t high_low = + ( CarryBits( lhs ) * rhs_low ) + CarryBits( low_low ); + // Note that we can add only low bits from high_low, to avoid + // overflow with large inputs + std::uint64_t low_high = + ( lhs_low * CarryBits( rhs ) ) + Digits( high_low ); + return { high_high + CarryBits( high_low ) + CarryBits( low_high ), + ( low_high << 32 ) | Digits( low_low ) }; #undef CarryBits #undef Digits - - return { - a << 32 | b, // upper 64 bits - c << 32 | d // lower 64 bits - }; } + //! Returns 128 bit result of lhs * rhs + inline ExtendedMultResult + extendedMult( std::uint64_t lhs, std::uint64_t rhs ) { +#if defined( CATCH_CONFIG_UINT128 ) + auto result = __uint128_t( lhs ) * __uint128_t( rhs ); + return { static_cast( result >> 64 ), + static_cast( result ) }; +#elif defined( CATCH_CONFIG_MSVC_UMUL128 ) + std::uint64_t high; + std::uint64_t low = _umul128( lhs, rhs, &high ); + return { high, low }; +#else + return extendedMultPortable( lhs, rhs ); +#endif + } + + template constexpr ExtendedMultResult extendedMult( UInt lhs, UInt rhs ) { static_assert( std::is_unsigned::value, @@ -8123,22 +8149,6 @@ namespace Catch { namespace Catch { - namespace Detail { - // Indirection to enable make_unsigned behaviour. - template - struct make_unsigned { - using type = std::make_unsigned_t; - }; - - template <> - struct make_unsigned { - using type = uint8_t; - }; - - template - using make_unsigned_t = typename make_unsigned::type; - } - /** * Implementation of uniform distribution on integers. * @@ -8154,7 +8164,7 @@ template class uniform_integer_distribution { static_assert(std::is_integral::value, "..."); - using UnsignedIntegerType = Detail::make_unsigned_t; + using UnsignedIntegerType = Detail::SizedUnsignedType_t; // Only the left bound is stored, and we store it converted to its // unsigned image. This avoids having to do the conversions inside @@ -10823,6 +10833,8 @@ namespace Catch { std::vector const& getAllTests() const override; std::vector const& getAllTestsSorted( IConfig const& config ) const override; + ~TestRegistry() override; // = default + private: std::vector> m_owned_test_infos; // Keeps a materialized vector for `getAllInfos`. diff --git a/meson.build b/meson.build index 3d0e715e..7c216f96 100644 --- a/meson.build +++ b/meson.build @@ -8,7 +8,7 @@ project( 'catch2', 'cpp', - version: '3.5.3', # CML version placeholder, don't delete + version: '3.5.4', # CML version placeholder, don't delete license: 'BSL-1.0', meson_version: '>=0.54.1', ) diff --git a/src/catch2/catch_version.cpp b/src/catch2/catch_version.cpp index 2604be35..9e8765b3 100644 --- a/src/catch2/catch_version.cpp +++ b/src/catch2/catch_version.cpp @@ -36,7 +36,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 3, 5, 3, "", 0 ); + static Version version( 3, 5, 4, "", 0 ); return version; } diff --git a/src/catch2/catch_version_macros.hpp b/src/catch2/catch_version_macros.hpp index 921ff526..ff50c09c 100644 --- a/src/catch2/catch_version_macros.hpp +++ b/src/catch2/catch_version_macros.hpp @@ -10,6 +10,6 @@ #define CATCH_VERSION_MAJOR 3 #define CATCH_VERSION_MINOR 5 -#define CATCH_VERSION_PATCH 3 +#define CATCH_VERSION_PATCH 4 #endif // CATCH_VERSION_MACROS_HPP_INCLUDED