<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/94879>94879</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[libcxx] Trying to use `atomic_ref<const T>` and `atomic_ref<volatile T>` fails with a compilation error
</td>
</tr>
<tr>
<th>Labels</th>
<td>
libc++
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
lewissbaker
</td>
</tr>
</table>
<pre>
The following code fails to compile, complaining that it cannot pass a `const T*` or `volatile T*` to the relevant intrinsic.
```c++
int i = 0;
std::atomic_ref<const int> cref(i);
int val = cref.load(); // error
cref.wait(); // error
volatile int vi = 0;
std::atomic_ref<volatile int> vref(v);
val = vref.load(); // error
vref.exchange(val); // error
vref.compare_exchange_weak(val, 0); // error
vref.compare_exchange_strong(val, 0); // error
vref.wait(0); // error
```
See https://godbolt.org/z/TbjYdd3Kx
The problem is that the local variable `__ret` used to receive the result of a load has type `_Tp*`, whereas it really needs to have type `remove_cv_t<_Tp>*`.
e.g. you can fix the `atomic_ref::load()` method by applying the following change:
```diff
_LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __order = memory_order::seq_cst) const noexcept
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__order) {
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
__order == memory_order::relaxed || __order == memory_order::consume || __order == memory_order::acquire ||
__order == memory_order::seq_cst,
"atomic_ref: memory order argument to atomic load operation is invalid");
alignas(_Tp) byte __mem[sizeof(_Tp)];
- auto* __ret = reinterpret_cast<_Tp*>(__mem);
+ auto* __ret = reinterpret_cast<remove_cv_t<_Tp>*>(__mem);
__atomic_load(__ptr_, __ret, std::__to_gcc_order(__order));
return *__ret;
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUVluPmzoX_TXOy1YjxpDbQx7I7WvUTqfK5NNRnywDO8GtwdQ2JOmvPzImOUx6OTmjCEb2XsvLm7W3zY0RxxJxTkYLMloNeG1zpecST8KYhH9DPUhUdpnvc4SDklKdRHmEVGUIBy6kAasgVUUlJBK6bP-VXJQuyObcgrCQ8rJUFipuDHAg4yBVpbGwJzQm4wCUdmONktwKibdhq8DmCBolNry0IEqrRWlEOiTBigRx9xwH_pcSunC_dlS4eCDhCgISdmPGZiSMSRhzqwqRMo0HEi69FFFaEq4hdWN0Kgid3WCOquGyJXPzQ6l4RujUxwChG0I3gFor7QFt0IkL-6cg_7ztuV3kMcF9jNPceM1NX_NVb_OI3jYIz2nOyyM6Ji7_HOs-MdfIrhh2Qv7tClxC8B_RxmpVHh_Gd5n9fdTNEf1MvyIC5NZWxqW0xRxVlihph0ofCd38IHSzT75-ybLww7mPdL6vtEokFiCM97TzpVQpl9BwLXgi0TmYMY3WObc2mDn7akxRNNjZ2NTSgjoAB_dFIOcG7KXyyH3lTe_2f8pRIzeucDRyKS9QImZtneXcsXUgjYVqkKUNsyRcOopw7VneFAgOj0O4qNpVIRzEuVVDxkHfVM5kPZuMAyjQ5iqD5AK8quTFV_ObBuDtEt6XYSYOBz8EAOzjdrH8_Jm9367WbLN7eWbxYgtsX0G3WoGF0hemdIYaWPd2zu1PeH0Gv7PUWEJn4Gu2VHhOsbLdate1lu_Xyw_s40u8Ys_r55fdF_ayW613hE47fsdAJos7WPz6ut7tWbz73_-f15_27K_t_v32E1u9PMfbTy4v1z35v57WX8vVKPkZMyCTJZks_z3e7aku8OF4nn6vhb7G36l7SOEtofdoQukbc3RY8HxcH-sCS-v86MO8n1WFmluhSlclomy4FBmhtN-WWnYuxbHkxn0P5_oZJBeLwFiBBRktjPiB6nCbJKPVDf2uRddWERpDW2utUzSK0qKuNFqWcnOtBRq35TD1xD0RhC4eY_ldff2aFhjrktZZm7HKauYK2vcFuoRbQ2fMKnZM06she9b8KV8aba1LIDT2PL1JMlndVd8gm4fZLJzxAc6fJk-T6WwSBXSQz0c4ioJsmo6iNDlElGfRNOAZRhjxcIJBMhBzGtAoGAez4CkKKR0eQj7KkizIZodkxIMnEgVYcCGHUjaFa5oDYUyN81k0ncwGkicoTXuHoFSK5HoaU-ruFHruQO-S-mhIFEhhrPmHxgor29uHg53PZLSCvfYdR7lWet-sltfbQ7h2nYqX2U8RvbuED_I3lZOwOfDutuK92p4bg1rL-d3hIGxeJ-6wInTjpHavd5VWXzG1hG7a7RtCNz4DzZz-HQAA__9WQtWu">