boost-ext / sml

C++14 State Machine library
https://boost-ext.github.io/sml
Boost Software License 1.0
1.16k stars 179 forks source link

GCC 11 + Google Tests / Mocks error #546

Open ladislas opened 1 year ago

ladislas commented 1 year ago

Expected Behavior

Running boost::sml in GT/M compiled with gcc@11 should work

Actual Behavior

We are working on transitioning from gcc@10 to gcc@11 and we are facing a strange issue:

In file included from /usr/include/c++/11/bits/move.h:57,
                 from /usr/include/c++/11/bits/stl_pair.h:59,
                 from /usr/include/c++/11/utility:70,
                 from /usr/include/c++/11/array:38,
                 from /home/runner/work/LekaOS/LekaOS/libs/LogKit/include/LogKit.h:7,
                 from /home/runner/work/LekaOS/LekaOS/libs/RobotKit/include/RCLogger.h:7,
                 from /home/runner/work/LekaOS/LekaOS/libs/RobotKit/tests/StateMachine_test.cpp:8:
/usr/include/c++/11/type_traits: In instantiation of ‘struct std::is_invocable_r<void, void (*&)(const char*, long unsigned int), const char*, long unsigned int>’:
/usr/include/c++/11/type_traits:3266:44:   required from ‘constexpr const bool std::is_invocable_r_v<void, void (*&)(const char*, long unsigned int), const char*, long unsigned int>’
/usr/include/c++/11/bits/invoke.h:103:27:   required by substitution of ‘template<class _Res, class _Callable, class ... _Args> constexpr std::enable_if_t<is_invocable_r_v<_Res, _Callable, _Args ...>, _Res> std::__invoke_r(_Callable&&, _Args&& ...) [with _Res = void; _Callable = void (*&)(const char*, long unsigned int); _Args = {const char*, long unsigned int}]’
/usr/include/c++/11/bits/std_function.h:290:30:   required from ‘static _Res std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes&& ...) [with _Res = void; _Functor = void (*)(const char*, long unsigned int); _ArgTypes = {const char*, long unsigned int}]’
/usr/include/c++/11/bits/std_function.h:451:21:   required from ‘std::function<_Res(_ArgTypes ...)>::function(_Functor&&) [with _Functor = void (&)(const char*, long unsigned int); _Constraints = void; _Res = void; _ArgTypes = {const char*, long unsigned int}]’
/home/runner/work/LekaOS/LekaOS/libs/LogKit/include/LogKit.h:178:32:   required from here
/usr/include/c++/11/type_traits:3030:7: error: could not convert ‘boost::ext::sml::v1_1_6::operator&&<std::integral_constant<bool, true>, std::integral_constant<bool, true> >(std::__is_complete_or_unbounded<const char*>((std::__type_identity<const char*>{}, std::__type_identity<const char*>())), std::__is_complete_or_unbounded<long unsigned int>((std::__type_identity<long unsigned int>{}, std::__type_identity<long unsigned int>())))’ from ‘boost::ext::sml::v1_1_6::front::and_<boost::ext::sml::v1_1_6::aux::zero_wrapper<std::integral_constant<bool, true>, void>, boost::ext::sml::v1_1_6::aux::zero_wrapper<std::integral_constant<bool, true>, void> >’ to ‘bool’
 3030 |       static_assert((std::__is_complete_or_unbounded(
      |       ^~~~~~~~~~~~~
      |       |
      |       boost::ext::sml::v1_1_6::front::and_<boost::ext::sml::v1_1_6::aux::zero_wrapper<std::integral_constant<bool, true>, void>, boost::ext::sml::v1_1_6::aux::zero_wrapper<std::integral_constant<bool, true>, void> >

And it goes on and on, as you can see here:

https://github.com/leka/LekaOS/actions/runs/3533489312/jobs/5929179683#step:6:1103

Test code in question:

https://github.com/leka/LekaOS/blob/develop/libs/RobotKit/tests/StateMachine_test.cpp#L36

I'm not even sure what could be the issue, those templates are very hard to read and understand :(

Steps to Reproduce the Problem

n/a

Specifications

ladislas commented 1 year ago

Funny enough, everything works perfectly well with gcc@12

https://github.com/leka/LekaOS/actions/runs/3547366195/jobs/5957407636#step:6:5130

samrimington commented 1 year ago

I came across a similar error with GCC 11 + Boost::SML. Upgrading to GCC 12 was unfortunately not an option for me.

I discovered that the issue lied in the using-directive for the entire Boost::SML namespace, which triggered some strange type conversions. I only needed access to literals so I changed:

using namespace boost::sml;

to

using namespace boost::sml::literals;