From f9157802a722ac822729f27961cbe13d25565d0a Mon Sep 17 00:00:00 2001 From: Christopher Kohlhoff Date: Mon, 1 Dec 2025 22:49:47 +1100 Subject: [PATCH] Ensure coroutine case labels are deterministic when __COUNTER__ is used. Coroutine implementations can be included from multiple translation units in a different order. When __COUNTER__ is used (for MSVC), this means that the values yielded by __COUNTER__ for a particular coroutine can differ between TUs. --- include/boost/asio/coroutine.hpp | 38 +++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/include/boost/asio/coroutine.hpp b/include/boost/asio/coroutine.hpp index f736ea0e..6469bae5 100644 --- a/include/boost/asio/coroutine.hpp +++ b/include/boost/asio/coroutine.hpp @@ -276,12 +276,34 @@ private: bool modified_; }; +class coroutine_base_value +{ +public: + constexpr coroutine_base_value(int value) : value_(value) {} + constexpr operator bool() const { return false; } + constexpr int get() const { return value_; } +private: + int value_; +}; + } // namespace detail } // namespace asio } // namespace boost +#if !defined(BOOST_ASIO_CORO_VALUE_INIT) +# if defined(_MSC_VER) +# define BOOST_ASIO_CORO_VALUE_INIT __COUNTER__ +# else // defined(_MSC_VER) +# define BOOST_ASIO_CORO_VALUE_INIT __LINE__ +# endif // defined(_MSC_VER) +#endif // !defined(BOOST_ASIO_CORO_VALUE_INIT) + #define BOOST_ASIO_CORO_REENTER(c) \ - switch (::boost::asio::detail::coroutine_ref _coro_value = c) \ + if (constexpr ::boost::asio::detail::coroutine_base_value \ + _coro_base_value = BOOST_ASIO_CORO_VALUE_INIT) \ + { \ + } \ + else switch (::boost::asio::detail::coroutine_ref _coro_value = c) \ case -1: if (_coro_value) \ { \ goto terminate_coroutine; \ @@ -319,12 +341,12 @@ private: } \ else -#if defined(_MSC_VER) -# define BOOST_ASIO_CORO_YIELD BOOST_ASIO_CORO_YIELD_IMPL(__COUNTER__ + 1) -# define BOOST_ASIO_CORO_FORK BOOST_ASIO_CORO_FORK_IMPL(__COUNTER__ + 1) -#else // defined(_MSC_VER) -# define BOOST_ASIO_CORO_YIELD BOOST_ASIO_CORO_YIELD_IMPL(__LINE__) -# define BOOST_ASIO_CORO_FORK BOOST_ASIO_CORO_FORK_IMPL(__LINE__) -#endif // defined(_MSC_VER) +# define BOOST_ASIO_CORO_YIELD \ + BOOST_ASIO_CORO_YIELD_IMPL( \ + BOOST_ASIO_CORO_VALUE_INIT + 1 - _coro_base_value.get()) + +# define BOOST_ASIO_CORO_FORK \ + BOOST_ASIO_CORO_FORK_IMPL( \ + BOOST_ASIO_CORO_VALUE_INIT + 1 - _coro_base_value.get()) #endif // BOOST_ASIO_COROUTINE_HPP