Skip to content

Commit 9ab9480

Browse files
committed
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.
1 parent e048fea commit 9ab9480

File tree

1 file changed

+30
-8
lines changed

1 file changed

+30
-8
lines changed

include/asio/coroutine.hpp

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -275,11 +275,33 @@ class coroutine_ref
275275
bool modified_;
276276
};
277277

278+
class coroutine_base_value
279+
{
280+
public:
281+
constexpr coroutine_base_value(int value) : value_(value) {}
282+
constexpr operator bool() const { return false; }
283+
constexpr int get() const { return value_; }
284+
private:
285+
int value_;
286+
};
287+
278288
} // namespace detail
279289
} // namespace asio
280290

291+
#if !defined(ASIO_CORO_VALUE_INIT)
292+
# if defined(_MSC_VER)
293+
# define ASIO_CORO_VALUE_INIT __COUNTER__
294+
# else // defined(_MSC_VER)
295+
# define ASIO_CORO_VALUE_INIT __LINE__
296+
# endif // defined(_MSC_VER)
297+
#endif // !defined(ASIO_CORO_VALUE_INIT)
298+
281299
#define ASIO_CORO_REENTER(c) \
282-
switch (::asio::detail::coroutine_ref _coro_value = c) \
300+
if (constexpr ::asio::detail::coroutine_base_value \
301+
_coro_base_value = ASIO_CORO_VALUE_INIT) \
302+
{ \
303+
} \
304+
else switch (::asio::detail::coroutine_ref _coro_value = c) \
283305
case -1: if (_coro_value) \
284306
{ \
285307
goto terminate_coroutine; \
@@ -317,12 +339,12 @@ class coroutine_ref
317339
} \
318340
else
319341

320-
#if defined(_MSC_VER)
321-
# define ASIO_CORO_YIELD ASIO_CORO_YIELD_IMPL(__COUNTER__ + 1)
322-
# define ASIO_CORO_FORK ASIO_CORO_FORK_IMPL(__COUNTER__ + 1)
323-
#else // defined(_MSC_VER)
324-
# define ASIO_CORO_YIELD ASIO_CORO_YIELD_IMPL(__LINE__)
325-
# define ASIO_CORO_FORK ASIO_CORO_FORK_IMPL(__LINE__)
326-
#endif // defined(_MSC_VER)
342+
# define ASIO_CORO_YIELD \
343+
ASIO_CORO_YIELD_IMPL( \
344+
ASIO_CORO_VALUE_INIT + 1 - _coro_base_value.get())
345+
346+
# define ASIO_CORO_FORK \
347+
ASIO_CORO_FORK_IMPL( \
348+
ASIO_CORO_VALUE_INIT + 1 - _coro_base_value.get())
327349

328350
#endif // ASIO_COROUTINE_HPP

0 commit comments

Comments
 (0)