Skip to content

Commit f328360

Browse files
committed
Fix atomic_ref narrow-type memcheck false positive
1 parent 48ff637 commit f328360

File tree

5 files changed

+496
-4
lines changed

5 files changed

+496
-4
lines changed

libcudacxx/include/cuda/std/__atomic/types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <cuda/std/__atomic/types/base.h>
2525
#include <cuda/std/__atomic/types/locked.h>
2626
#include <cuda/std/__atomic/types/reference.h>
27+
#include <cuda/std/__atomic/types/reference_small.h>
2728
#include <cuda/std/__atomic/types/small.h>
2829
#include <cuda/std/__type_traits/conditional.h>
2930

libcudacxx/include/cuda/std/__atomic/types/common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ enum class __atomic_tag
3636
__atomic_base_tag,
3737
__atomic_locked_tag,
3838
__atomic_small_tag,
39+
__atomic_ref_small_tag,
3940
};
4041

4142
// Helpers to SFINAE on the tag inside the storage object
@@ -45,6 +46,8 @@ template <typename _Sto>
4546
using __atomic_storage_is_locked = enable_if_t<__atomic_tag::__atomic_locked_tag == remove_cvref_t<_Sto>::__tag, int>;
4647
template <typename _Sto>
4748
using __atomic_storage_is_small = enable_if_t<__atomic_tag::__atomic_small_tag == remove_cvref_t<_Sto>::__tag, int>;
49+
template <typename _Sto>
50+
using __atomic_storage_is_ref_small = enable_if_t<__atomic_tag::__atomic_ref_small_tag == remove_cvref_t<_Sto>::__tag, int>;
4851

4952
template <typename _Tp>
5053
using __atomic_underlying_t = typename _Tp::__underlying_t;

libcudacxx/include/cuda/std/__atomic/types/reference.h

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@
2828

2929
_CCCL_BEGIN_NAMESPACE_CUDA_STD
3030

31-
// Reference is compatible with __atomic_base_tag and uses the default dispatch
31+
template <typename _Tp, bool _IsSmall>
32+
struct __atomic_ref_storage_impl;
33+
3234
template <typename _Tp>
33-
struct __atomic_ref_storage
35+
struct __atomic_ref_storage_impl<_Tp, false>
3436
{
3537
using __underlying_t = _Tp;
3638
static constexpr __atomic_tag __tag = __atomic_tag::__atomic_base_tag;
@@ -41,9 +43,9 @@ struct __atomic_ref_storage
4143

4244
_Tp* __a_value;
4345

44-
__atomic_ref_storage() = delete;
46+
__atomic_ref_storage_impl() = delete;
4547

46-
_CCCL_HOST_DEVICE constexpr explicit inline __atomic_ref_storage(_Tp* value) noexcept
48+
_CCCL_HOST_DEVICE constexpr explicit inline __atomic_ref_storage_impl(_Tp* value) noexcept
4749
: __a_value(value)
4850
{}
4951

@@ -65,6 +67,45 @@ struct __atomic_ref_storage
6567
}
6668
};
6769

70+
template <typename _Tp>
71+
struct __atomic_ref_storage_impl<_Tp, true>
72+
{
73+
using __underlying_t = _Tp;
74+
static constexpr __atomic_tag __tag = __atomic_tag::__atomic_ref_small_tag;
75+
76+
#if !_CCCL_COMPILER(GCC) || _CCCL_COMPILER(GCC, >=, 5)
77+
static_assert(is_trivially_copyable_v<_Tp>, "std::atomic_ref<Tp> requires that 'Tp' be a trivially copyable type");
78+
#endif
79+
80+
_Tp* __a_value;
81+
82+
__atomic_ref_storage_impl() = delete;
83+
84+
_CCCL_HOST_DEVICE constexpr explicit inline __atomic_ref_storage_impl(_Tp* value) noexcept
85+
: __a_value(value)
86+
{}
87+
88+
_CCCL_HOST_DEVICE inline auto get() noexcept -> __underlying_t*
89+
{
90+
return __a_value;
91+
}
92+
_CCCL_HOST_DEVICE inline auto get() const noexcept -> __underlying_t*
93+
{
94+
return __a_value;
95+
}
96+
_CCCL_HOST_DEVICE inline auto get() volatile noexcept -> volatile __underlying_t*
97+
{
98+
return __a_value;
99+
}
100+
_CCCL_HOST_DEVICE inline auto get() const volatile noexcept -> volatile __underlying_t*
101+
{
102+
return __a_value;
103+
}
104+
};
105+
106+
template <typename _Tp>
107+
using __atomic_ref_storage = __atomic_ref_storage_impl<_Tp, (sizeof(_Tp) < 4)>;
108+
68109
_CCCL_END_NAMESPACE_CUDA_STD
69110

70111
#include <cuda/std/__cccl/epilogue.h>

0 commit comments

Comments
 (0)