From 644821ce28cb25d7992a4d0375b1d83214392592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sat, 9 Aug 2025 00:30:23 +0200 Subject: [PATCH] v3.9.1 --- CMakeLists.txt | 2 +- docs/release-notes.md | 14 +++++ extras/catch_amalgamated.cpp | 17 ++++-- extras/catch_amalgamated.hpp | 85 ++++++++++++++++++++--------- meson.build | 2 +- src/catch2/catch_version.cpp | 2 +- src/catch2/catch_version_macros.hpp | 2 +- 7 files changed, 88 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1676ee79..4b4e4f58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ if(CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) endif() project(Catch2 - VERSION 3.9.0 # CML version placeholder, don't delete + VERSION 3.9.1 # CML version placeholder, don't delete LANGUAGES CXX HOMEPAGE_URL "https://github.com/catchorg/Catch2" DESCRIPTION "A modern, C++-native, unit test framework." diff --git a/docs/release-notes.md b/docs/release-notes.md index b8b973c9..6f9ee6a1 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -2,6 +2,7 @@ # Release notes **Contents**
+[3.9.1](#391)
[3.9.0](#390)
[3.8.1](#381)
[3.8.0](#380)
@@ -68,6 +69,19 @@ [Even Older versions](#even-older-versions)
+## 3.9.1 + +### Fixes +* Fixed bad error reporting for multiple nested assertions (#1292) +* Fixed W4702 (unreachable code) in the polyfill for std::unreachable (#3007) +* Fixed decomposition of assertions comparing enum-backed bitfields (#3001) +* Fixed StringMaker specialization for `time_point` with non-default duration type (#2685) + +### Improvements +* Exceptions thrown during stringification of decomposed expression no longer fail the assertion (#2980) +* The selection logic for `CATCH_TRAP` prefers `__builtin_debugtrap` on all platforms when Catch2 is compiled with Clang + + ## 3.9.0 ### Improvements diff --git a/extras/catch_amalgamated.cpp b/extras/catch_amalgamated.cpp index 3a9cd757..79ec8d1a 100644 --- a/extras/catch_amalgamated.cpp +++ b/extras/catch_amalgamated.cpp @@ -6,8 +6,8 @@ // SPDX-License-Identifier: BSL-1.0 -// Catch v3.9.0 -// Generated: 2025-07-24 22:00:25.173359 +// Catch v3.9.1 +// Generated: 2025-08-09 00:29:21.552225 // ---------------------------------------------------------- // This file is an amalgamation of multiple different files. // You probably shouldn't edit it directly. @@ -2026,6 +2026,13 @@ namespace Detail { rss << std::setw(2) << static_cast(bytes[i]); return rss.str(); } + + std::string makeExceptionHappenedString() { + return "{ stringification failed with an exception: \"" + + translateActiveException() + "\" }"; + + } + } // end Detail namespace @@ -2271,7 +2278,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 3, 9, 0, "", 0 ); + static Version version( 3, 9, 1, "", 0 ); return version; } @@ -3981,10 +3988,10 @@ namespace Catch { // To avoid having to handle TFE explicitly everywhere, we just // rethrow it so that it goes back up the caller. catch( TestFailureException& ) { - std::rethrow_exception(std::current_exception()); + return "{ nested assertion failed }"; } catch( TestSkipException& ) { - std::rethrow_exception(std::current_exception()); + return "{ nested SKIP() called }"; } catch( std::exception const& ex ) { return ex.what(); diff --git a/extras/catch_amalgamated.hpp b/extras/catch_amalgamated.hpp index 608a184b..7e331cc8 100644 --- a/extras/catch_amalgamated.hpp +++ b/extras/catch_amalgamated.hpp @@ -6,8 +6,8 @@ // SPDX-License-Identifier: BSL-1.0 -// Catch v3.9.0 -// Generated: 2025-07-24 22:00:24.654688 +// Catch v3.9.1 +// Generated: 2025-08-09 00:29:20.303175 // ---------------------------------------------------------- // This file is an amalgamation of multiple different files. // You probably shouldn't edit it directly. @@ -958,7 +958,7 @@ namespace Detail { } explicit operator bool() const { - return m_ptr; + return m_ptr != nullptr; } friend void swap(unique_ptr& lhs, unique_ptr& rhs) { @@ -2151,9 +2151,7 @@ namespace Catch { auto analysis = Detail::analyse(*cfg, samples.data(), samples.data() + samples.size()); BenchmarkStats<> stats{ CATCH_MOVE(info), CATCH_MOVE(analysis.samples), analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance }; getResultCapture().benchmarkEnded(stats); - } CATCH_CATCH_ANON (TestFailureException const&) { - getResultCapture().benchmarkFailed("Benchmark failed due to failed assertion"_sr); - } CATCH_CATCH_ALL{ + } CATCH_CATCH_ALL { getResultCapture().benchmarkFailed(translateActiveException()); // We let the exception go further up so that the // test case is marked as failed. @@ -2566,11 +2564,17 @@ namespace Catch { namespace Detail { + std::string makeExceptionHappenedString(); + // This function dispatches all stringification requests inside of Catch. // Should be preferably called fully qualified, like ::Catch::Detail::stringify template - std::string stringify(const T& e) { - return ::Catch::StringMaker>>::convert(e); + std::string stringify( const T& e ) { + CATCH_TRY { + return ::Catch::StringMaker< + std::remove_cv_t>>::convert( e ); + } + CATCH_CATCH_ALL { return makeExceptionHappenedString(); } } template @@ -3053,17 +3057,19 @@ struct ratio_string { template struct StringMaker> { static std::string convert(std::chrono::time_point const& time_point) { - auto converted = std::chrono::system_clock::to_time_t(time_point); + const auto systemish = std::chrono::time_point_cast< + std::chrono::system_clock::duration>( time_point ); + const auto as_time_t = std::chrono::system_clock::to_time_t( systemish ); #ifdef _MSC_VER std::tm timeInfo = {}; - const auto err = gmtime_s(&timeInfo, &converted); + const auto err = gmtime_s( &timeInfo, &as_time_t ); if ( err ) { return "gmtime from provided timepoint has failed. This " "happens e.g. with pre-1970 dates using Microsoft libc"; } #else - std::tm* timeInfo = std::gmtime(&converted); + std::tm* timeInfo = std::gmtime( &as_time_t ); #endif auto const timeStampSize = sizeof("2017-01-16T17:06:45Z"); @@ -5238,10 +5244,11 @@ namespace Detail { * * 3) If a type has no linkage, we also cannot capture it by reference. * The solution is once again to capture them by value. We handle - * the common cases by using `std::is_arithmetic` as the default - * for `Catch::capture_by_value`, but that is only a some-effort - * heuristic. But as with 2), users can specialize `capture_by_value` - * for their own types as needed. + * the common cases by using `std::is_arithmetic` and `std::is_enum` + * as the default for `Catch::capture_by_value`, but that is only a + * some-effort heuristic. These combine to capture all possible bitfield + * bases, and also some trait-like types. As with 2), users can + * specialize `capture_by_value` for their own types as needed. * * 4) To support C++20 and make the SFINAE on our decomposing operators * work, the SFINAE has to happen in return type, rather than in @@ -5293,13 +5300,22 @@ namespace Catch { 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 - // keep this as it used to be and it can be changed later. + // Note: This is about as much as we can currently reasonably support. + // In an ideal world, we could capture by value small trivially + // copyable types, but the actual `std::is_trivially_copyable` + // trait is a huge mess with standard-violating results on + // GCC and Clang, which are unlikely to be fixed soon due to ABI + // concerns. + // `std::is_scalar` also causes issues due to the `is_pointer` + // component, which causes ambiguity issues with (references-to) + // function pointer. If those are resolved, we still need to + // disambiguate the overload set for arrays, through explicit + // overload for references to sized arrays. template struct capture_by_value - : std::integral_constant{}> {}; + : std::integral_constant::value || + std::is_enum::value> {}; #if defined( CATCH_CONFIG_CPP20_COMPARE_OVERLOADS ) template <> @@ -6241,9 +6257,13 @@ namespace Catch { __assume( false ); # elif defined( __GNUC__ ) __builtin_unreachable(); -# endif -# endif // ^^ NDEBUG +# else // vv platform without known optimization hint std::terminate(); +# endif +# else // ^^ NDEBUG + // For non-release builds, we prefer termination on bug over UB + std::terminate(); +# endif // } } // namespace Detail @@ -7447,7 +7467,7 @@ namespace Catch { #define CATCH_VERSION_MAJOR 3 #define CATCH_VERSION_MINOR 9 -#define CATCH_VERSION_PATCH 0 +#define CATCH_VERSION_PATCH 1 #endif // CATCH_VERSION_MACROS_HPP_INCLUDED @@ -9500,6 +9520,17 @@ namespace Catch { bool isDebuggerActive(); } +#if !defined( CATCH_TRAP ) && defined( __clang__ ) && defined( __has_builtin ) +# if __has_builtin( __builtin_debugtrap ) +# define CATCH_TRAP() __builtin_debugtrap() +# endif +#endif + +#if !defined( CATCH_TRAP ) && defined( _MSC_VER ) +# define CATCH_TRAP() __debugbreak() +#endif + +#if !defined(CATCH_TRAP) // If we couldn't use compiler-specific impl from above, we get into platform-specific options #ifdef CATCH_PLATFORM_MAC #if defined(__i386__) || defined(__x86_64__) @@ -9535,15 +9566,15 @@ namespace Catch { #define CATCH_TRAP() raise(SIGTRAP) #endif -#elif defined(_MSC_VER) - #define CATCH_TRAP() __debugbreak() #elif defined(__MINGW32__) extern "C" __declspec(dllimport) void __stdcall DebugBreak(); #define CATCH_TRAP() DebugBreak() #endif +#endif // ^^ CATCH_TRAP is not defined yet, so we define it -#ifndef CATCH_BREAK_INTO_DEBUGGER - #ifdef CATCH_TRAP + +#if !defined(CATCH_BREAK_INTO_DEBUGGER) + #if defined(CATCH_TRAP) #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }() #else #define CATCH_BREAK_INTO_DEBUGGER() []{}() diff --git a/meson.build b/meson.build index 021266d8..3e8abc5a 100644 --- a/meson.build +++ b/meson.build @@ -8,7 +8,7 @@ project( 'catch2', 'cpp', - version: '3.9.0', # CML version placeholder, don't delete + version: '3.9.1', # 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 a012101e..8c9d1c7f 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, 9, 0, "", 0 ); + static Version version( 3, 9, 1, "", 0 ); return version; } diff --git a/src/catch2/catch_version_macros.hpp b/src/catch2/catch_version_macros.hpp index a795e4ba..eac8d0e5 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 9 -#define CATCH_VERSION_PATCH 0 +#define CATCH_VERSION_PATCH 1 #endif // CATCH_VERSION_MACROS_HPP_INCLUDED