diff --git a/README.md b/README.md index d088f8375..b6928921d 100644 --- a/README.md +++ b/README.md @@ -209,3 +209,7 @@ The coverage is generated via ``gcov`` and evaluated by | AppleClang-18.1.6 | - | x | x | x | As new compilers become available, they will be added to the workflow, but older compilers will probably never be supported. + +## Known Issues + +* Clang-18.1 introduced a regression regarding the ``std::invocable`` concept and a default parameter of type ``std::source_location``. On this version, all invocable checks will fail. Clang-17 and Clang-19 do not suffer from this issue. diff --git a/test/unit-tests/Mock.cpp b/test/unit-tests/Mock.cpp index a37050326..0ba171ce8 100644 --- a/test/unit-tests/Mock.cpp +++ b/test/unit-tests/Mock.cpp @@ -19,6 +19,20 @@ using namespace mimicpp; +// This disables the std::invocable checks for Mocks, due to an issue on clang 18.1 +// see: https://github.com/llvm/llvm-project/issues/106428 +#if defined(__clang_major__) \ + && __clang_major__ == 18 \ + && __clang_minor__ == 1 + + #define CLANG_18_STD_INVOCABLE_REGRESSION + + // Should fail, when the regression has been resolved. + // If so, enable the tests and remove the issue from the ``Known Issues`` section in the readme. + static_assert(!std::invocable>); + +#endif + TEMPLATE_TEST_CASE( "Mock is a non-copyable, but movable and default-constructible type.", "[mock]", @@ -66,23 +80,52 @@ TEMPLATE_TEST_CASE_SIG( using NothrowMockT = Mock>; STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); + + // negative checks + + STATIC_REQUIRE(!std::is_invocable_r_v); + STATIC_REQUIRE(!std::is_invocable_r_v); + + STATIC_REQUIRE(!std::is_invocable_r_v); + STATIC_REQUIRE(!std::is_invocable_r_v); + + STATIC_REQUIRE(!std::is_invocable_r_v); + STATIC_REQUIRE(!std::is_invocable_r_v); + +#ifndef CLANG_18_STD_INVOCABLE_REGRESSION + + STATIC_REQUIRE(std::invocable); + STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::invocable); + STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::invocable); + + // negative checks + + STATIC_REQUIRE(!std::invocable); + STATIC_REQUIRE(!std::invocable); + + STATIC_REQUIRE(!std::invocable); + STATIC_REQUIRE(!std::invocable); + + STATIC_REQUIRE(!std::invocable); + STATIC_REQUIRE(!std::invocable); + +#endif } TEMPLATE_TEST_CASE_SIG( - "Mutable Mock specialization is an invocable type.", + "Const Mock specialization is an invocable type.", "[mock]", ((bool dummy, typename Sig, typename... Args), dummy, Sig, Args...), (true, void() const), @@ -98,29 +141,44 @@ TEMPLATE_TEST_CASE_SIG( using NothrowMockT = Mock>; STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::is_invocable_r_v); + STATIC_REQUIRE(std::is_invocable_r_v); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); + +#ifndef CLANG_18_STD_INVOCABLE_REGRESSION + + STATIC_REQUIRE(std::invocable); + STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::invocable); + STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::invocable); + STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::invocable); + STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::invocable); + STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::invocable); + +#endif } TEMPLATE_TEST_CASE_SIG( @@ -140,9 +198,48 @@ TEMPLATE_TEST_CASE_SIG( using NothrowMockT = Mock>; STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); + + // negative checks + + STATIC_REQUIRE(!std::is_invocable_r_v); + STATIC_REQUIRE(!std::is_invocable_r_v); + + STATIC_REQUIRE(!std::is_invocable_r_v); + STATIC_REQUIRE(!std::is_invocable_r_v); + + STATIC_REQUIRE(!std::is_invocable_r_v); + STATIC_REQUIRE(!std::is_invocable_r_v); + + STATIC_REQUIRE(!std::is_invocable_r_v); + STATIC_REQUIRE(!std::is_invocable_r_v); + + STATIC_REQUIRE(!std::is_invocable_r_v); + STATIC_REQUIRE(!std::is_invocable_r_v); + +#ifndef CLANG_18_STD_INVOCABLE_REGRESSION + + STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::invocable); + + // negative checks + + STATIC_REQUIRE(!std::invocable); + STATIC_REQUIRE(!std::invocable); + + STATIC_REQUIRE(!std::invocable); + STATIC_REQUIRE(!std::invocable); + + STATIC_REQUIRE(!std::invocable); + STATIC_REQUIRE(!std::invocable); + + STATIC_REQUIRE(!std::invocable); + STATIC_REQUIRE(!std::invocable); + + STATIC_REQUIRE(!std::invocable); + STATIC_REQUIRE(!std::invocable); + +#endif } TEMPLATE_TEST_CASE_SIG( @@ -162,29 +259,44 @@ TEMPLATE_TEST_CASE_SIG( using NothrowMockT = Mock>; STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::is_invocable_r_v); + STATIC_REQUIRE(std::is_invocable_r_v); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); + +#ifndef CLANG_18_STD_INVOCABLE_REGRESSION + + STATIC_REQUIRE(std::invocable); + STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::invocable); + STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::invocable); + STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::invocable); + STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::invocable); + STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::invocable); + +#endif } TEMPLATE_TEST_CASE_SIG( @@ -204,14 +316,48 @@ TEMPLATE_TEST_CASE_SIG( using NothrowMockT = Mock>; STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); + + // negative checks + + STATIC_REQUIRE(!std::is_invocable_r_v); + STATIC_REQUIRE(!std::is_invocable_r_v); + + STATIC_REQUIRE(!std::is_invocable_r_v); + STATIC_REQUIRE(!std::is_invocable_r_v); + + STATIC_REQUIRE(!std::is_invocable_r_v); + STATIC_REQUIRE(!std::is_invocable_r_v); + + STATIC_REQUIRE(!std::is_invocable_r_v); + STATIC_REQUIRE(!std::is_invocable_r_v); + +#ifndef CLANG_18_STD_INVOCABLE_REGRESSION + + STATIC_REQUIRE(std::invocable); + STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::invocable); + + // negative checks + + STATIC_REQUIRE(!std::invocable); + STATIC_REQUIRE(!std::invocable); + + STATIC_REQUIRE(!std::invocable); + STATIC_REQUIRE(!std::invocable); + + STATIC_REQUIRE(!std::invocable); + STATIC_REQUIRE(!std::invocable); + + STATIC_REQUIRE(!std::invocable); + STATIC_REQUIRE(!std::invocable); + +#endif } TEMPLATE_TEST_CASE_SIG( @@ -231,19 +377,48 @@ TEMPLATE_TEST_CASE_SIG( using NothrowMockT = Mock>; STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::is_invocable_r_v); + STATIC_REQUIRE(std::is_invocable_r_v); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); - STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::is_invocable_r_v); + + // negative checks + + STATIC_REQUIRE(!std::is_invocable_r_v); + STATIC_REQUIRE(!std::is_invocable_r_v); + + STATIC_REQUIRE(!std::is_invocable_r_v); + STATIC_REQUIRE(!std::is_invocable_r_v); + +#ifndef CLANG_18_STD_INVOCABLE_REGRESSION + + STATIC_REQUIRE(std::invocable); + STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::invocable); + STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::invocable); + STATIC_REQUIRE(std::invocable); + + STATIC_REQUIRE(std::invocable); STATIC_REQUIRE(std::invocable); + + // negative checks + + STATIC_REQUIRE(!std::invocable); + STATIC_REQUIRE(!std::invocable); + + STATIC_REQUIRE(!std::invocable); + STATIC_REQUIRE(!std::invocable); + +#endif } TEST_CASE(