Index: include/atomic =================================================================== --- include/atomic +++ include/atomic @@ -584,10 +584,29 @@ _LIBCPP_BEGIN_NAMESPACE_STD +// Figure out what the underlying type for `memory_order` would be if it were +// declared as an unscoped enum (accounting for -fshort-enums). Use this result +// to pin the underlying type in C++20. +enum __legacy_memory_order { + __mo_relaxed, + __mo_consume, + __mo_acquire, + __mo_release, + __mo_acq_rel, + __mo_seq_cst +}; + +typedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t; + #if _LIBCPP_STD_VER > 17 -enum class memory_order { - relaxed, consume, acquire, release, acq_rel, seq_cst +enum class memory_order : __memory_order_underlying_t { + relaxed = __mo_relaxed, + consume = __mo_consume, + acquire = __mo_acquire, + release = __mo_release, + acq_rel = __mo_acq_rel, + seq_cst = __mo_seq_cst }; inline constexpr auto memory_order_relaxed = memory_order::relaxed; @@ -600,14 +619,18 @@ #else typedef enum memory_order { - memory_order_relaxed, memory_order_consume, memory_order_acquire, - memory_order_release, memory_order_acq_rel, memory_order_seq_cst + memory_order_relaxed = __mo_relaxed, + memory_order_consume = __mo_consume, + memory_order_acquire = __mo_acquire, + memory_order_release = __mo_release, + memory_order_acq_rel = __mo_acq_rel, + memory_order_seq_cst = __mo_seq_cst, } memory_order; #endif // _LIBCPP_STD_VER > 17 -typedef underlying_type::type __memory_order_underlying_t; - +static_assert(is_same::type, __memory_order_underlying_t>::value, + "unexpected underlying type for std::memory_order"); #if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \ defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)