[BUG]: libcudacxx clashes w/ libc++: ambiguous overload resolution for `__swallow`
Is this a duplicate?
- [X] I confirmed there appear to be no duplicate issues for this bug and that I agree to the Code of Conduct
Type of Bug
Compile-time Error
Component
libcu++
Describe the bug
https://godbolt.org/z/47xKeqKnM
Compilation fails because of an ambiguous overload resolution caused by both libcudacxx and libc++ providing overloads for __swallow:
/opt/compiler-explorer/clang-trunk-20240430/bin/../include/c++/v1/tuple:439:58: note: candidate function [with _Tp = <cuda::std::__tuple_leaf<0, std::__wrap_iter<int *>> &, cuda::std::__tuple_leaf<1, std::__wrap_iter<int *>> &>]
439 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __swallow(_Tp&&...) _NOEXCEPT {}
| ^
/opt/compiler-explorer/libs/cccl/trunk/libcudacxx/include/cuda/std/detail/libcxx/include/tuple:427:36: note: candidate function [with _Tp = <cuda::std::__tuple_leaf<0, std::__wrap_iter<int *>> &, cuda::std::__tuple_leaf<1, std::__wrap_iter<int *>> &>]
427 | _LIBCUDACXX_INLINE_VISIBILITY void __swallow(_Tp &&...) noexcept {}
| ^
How to Reproduce
Reproducer on godbolt: https://godbolt.org/z/47xKeqKnM
Expected behavior
No conflicts with libc++
Reproduction link
https://godbolt.org/z/47xKeqKnM
Operating System
Debian/testing
nvidia-smi output
N/a
NVCC version
NVCC does not support libc++.
The issue affects clang + libc++ only.
Looks like libcudacxx is missing this fix from libc++: https://reviews.llvm.org/D50106
Basically calls to __swallow need to be done with fully qualified name. I guess in libcudacxx it means _CUDA_VSTD::. The diff below appears to fix this issue.
diff --git a/libcudacxx/include/cuda/std/detail/libcxx/include/tuple b/libcudacxx/include/cuda/std/detail/libcxx/include/tuple
index 22cb1d51f..cc2682931 100644
--- a/libcudacxx/include/cuda/std/detail/libcxx/include/tuple
+++ b/libcudacxx/include/cuda/std/detail/libcxx/include/tuple
@@ -494,7 +494,7 @@ struct _LIBCUDACXX_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>,
_LIBCUDACXX_INLINE_VISIBILITY __tuple_impl& operator=(_Tuple&& __t) noexcept(
(__all<_LIBCUDACXX_TRAIT(is_nothrow_assignable, _Tp&, __tuple_elem_at<_Tuple, _Indx>)...>::value))
{
- __swallow(__tuple_leaf<_Indx, _Tp>::operator=(
+ _CUDA_VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::operator=(
_CUDA_VSTD::forward<__tuple_elem_at<_Tuple, _Indx>>(_CUDA_VSTD::get<_Indx>(__t)))...);
return *this;
}
@@ -505,14 +505,14 @@ struct _LIBCUDACXX_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>,
_LIBCUDACXX_INLINE_VISIBILITY __tuple_impl&
operator=(const __tuple_impl& __t) noexcept((__all<_LIBCUDACXX_TRAIT(is_nothrow_copy_assignable, _Tp)...>::value))
{
- __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);
+ _CUDA_VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);
return *this;
}
_LIBCUDACXX_INLINE_VISIBILITY __tuple_impl&
operator=(__tuple_impl&& __t) noexcept((__all<_LIBCUDACXX_TRAIT(is_nothrow_move_assignable, _Tp)...>::value))
{
- __swallow(__tuple_leaf<_Indx, _Tp>::operator=(
+ _CUDA_VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::operator=(
_CUDA_VSTD::forward<_Tp>(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t).get()))...);
return *this;
}
@@ -520,7 +520,7 @@ struct _LIBCUDACXX_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>,
_LIBCUDACXX_INLINE_VISIBILITY void
swap(__tuple_impl& __t) noexcept(__all<__is_nothrow_swappable<_Tp>::value...>::value)
{
- __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
+ _CUDA_VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
}
};
@jrhemstad, @miscco ^^^
I adopted this in #1685