diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0ad4ef5d..d8015737 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -144,6 +144,7 @@ set(IMPL_HEADERS ${SOURCES_DIR}/internal/catch_uniform_integer_distribution.hpp ${SOURCES_DIR}/internal/catch_unique_name.hpp ${SOURCES_DIR}/internal/catch_unique_ptr.hpp + ${SOURCES_DIR}/internal/catch_unreachable.hpp ${SOURCES_DIR}/internal/catch_void_type.hpp ${SOURCES_DIR}/internal/catch_wildcard_pattern.hpp ${SOURCES_DIR}/internal/catch_windows_h_proxy.hpp diff --git a/src/catch2/catch_all.hpp b/src/catch2/catch_all.hpp index 88dd57ea..0d173715 100644 --- a/src/catch2/catch_all.hpp +++ b/src/catch2/catch_all.hpp @@ -126,6 +126,7 @@ #include #include #include +#include #include #include #include diff --git a/src/catch2/catch_test_macros.hpp b/src/catch2/catch_test_macros.hpp index 6ee2129f..97708557 100644 --- a/src/catch2/catch_test_macros.hpp +++ b/src/catch2/catch_test_macros.hpp @@ -14,6 +14,7 @@ #include #include #include +#include // All of our user-facing macros support configuration toggle, that @@ -47,10 +48,16 @@ #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) #define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ ) - #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) + #define CATCH_FAIL( ... ) do { \ + INTERNAL_CATCH_MSG("CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ); \ + Catch::Detail::Unreachable(); \ + } while ( false ) #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) - #define CATCH_SKIP( ... ) INTERNAL_CATCH_MSG( "SKIP", Catch::ResultWas::ExplicitSkip, Catch::ResultDisposition::Normal, __VA_ARGS__ ) + #define CATCH_SKIP( ... ) do { \ + INTERNAL_CATCH_MSG( "CATCH_SKIP", Catch::ResultWas::ExplicitSkip, Catch::ResultDisposition::Normal, __VA_ARGS__ ); \ + Catch::Detail::Unreachable(); \ + } while (false) #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE) @@ -148,10 +155,16 @@ #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) #define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ ) - #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) + #define FAIL( ... ) do { \ + INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ); \ + Catch::Detail::Unreachable(); \ + } while (false) #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) - #define SKIP( ... ) INTERNAL_CATCH_MSG( "SKIP", Catch::ResultWas::ExplicitSkip, Catch::ResultDisposition::Normal, __VA_ARGS__ ) + #define SKIP( ... ) do { \ + INTERNAL_CATCH_MSG( "SKIP", Catch::ResultWas::ExplicitSkip, Catch::ResultDisposition::Normal, __VA_ARGS__ ); \ + Catch::Detail::Unreachable(); \ + } while (false) #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE) diff --git a/src/catch2/internal/catch_unreachable.hpp b/src/catch2/internal/catch_unreachable.hpp new file mode 100644 index 00000000..02cca494 --- /dev/null +++ b/src/catch2/internal/catch_unreachable.hpp @@ -0,0 +1,52 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#ifndef CATCH_UNREACHABLE_HPP_INCLUDED +#define CATCH_UNREACHABLE_HPP_INCLUDED + +/**\file + * Polyfill `std::unreachable` + * + * We need something like `std::unreachable` to tell the compiler that + * some macros, e.g. `FAIL` or `SKIP`, do not continue execution in normal + * manner, and should handle it as such, e.g. not warn if there is no return + * from non-void function after a `FAIL` or `SKIP`. + */ + +#include + +#if defined( __cpp_lib_unreachable ) && __cpp_lib_unreachable > 202202L +# include +namespace Catch { + namespace Detail { + using Unreachable = std::unreachable; + } +} // namespace Catch + +#else // vv If we do not have std::unreachable, we implement something similar + +namespace Catch { + namespace Detail { + + [[noreturn]] + inline void Unreachable() noexcept { +# if defined( NDEBUG ) +# if defined( _MSC_VER ) && !defined( __clang__ ) + __assume( false ); +# elif defined( __GNUC__ ) + __builtin_unreachable(); +# endif +# endif // ^^ NDEBUG + std::terminate(); + } + + } // namespace Detail +} // end namespace Catch + +#endif + +#endif // CATCH_UNREACHABLE_HPP_INCLUDED diff --git a/src/catch2/meson.build b/src/catch2/meson.build index 191aea3f..90a04f00 100644 --- a/src/catch2/meson.build +++ b/src/catch2/meson.build @@ -152,6 +152,7 @@ internal_headers = [ 'internal/catch_uniform_integer_distribution.hpp', 'internal/catch_unique_name.hpp', 'internal/catch_unique_ptr.hpp', + 'internal/catch_unreachable.hpp', 'internal/catch_void_type.hpp', 'internal/catch_wildcard_pattern.hpp', 'internal/catch_windows_h_proxy.hpp',