Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable system header for narrowing conversion check #2465

Merged
merged 1 commit into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//===----------------------------------------------------------------------===//
//
// Part of libcu++, the C++ Standard Library for your entire system,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//

#ifndef __CCCL_IS_NON_NARROWING_CONVERTIBLE_H
#define __CCCL_IS_NON_NARROWING_CONVERTIBLE_H

#include <cuda/std/__cccl/compiler.h>

//! There is compiler bug that results in incorrect results for the below `__is_non_narrowing_convertible` check.
//! This breaks some common functionality, so this *must* be included outside of a system header. See nvbug4867473.
#if defined(_CCCL_FORCE_SYSTEM_HEADER_GCC) || defined(_CCCL_FORCE_SYSTEM_HEADER_CLANG) \
|| defined(_CCCL_FORCE_SYSTEM_HEADER_MSVC)
# error \
"This header must be included only within the <cuda/std/__cccl/system_header>. This most likely means a mix and match of different versions of CCCL."
#endif // system header detected

namespace __cccl_internal
{

#if defined(_CCCL_CUDA_COMPILER) && (defined(__CUDACC__) || defined(_NVHPC_CUDA) || defined(_CCCL_COMPILER_NVRTC))
template <class _Tp>
__host__ __device__ _Tp&& __cccl_declval(int);
template <class _Tp>
__host__ __device__ _Tp __cccl_declval(long);
template <class _Tp>
__host__ __device__ decltype(__cccl_internal::__cccl_declval<_Tp>(0)) __cccl_declval() noexcept;

// This requires a type to be implicitly convertible (also non-arithmetic)
template <class _Tp>
__host__ __device__ void __cccl_accepts_implicit_conversion(_Tp) noexcept;
#else // ^^^ CUDA compilation ^^^ / vvv no CUDA compilation
template <class _Tp>
_Tp&& __cccl_declval(int);
template <class _Tp>
_Tp __cccl_declval(long);
template <class _Tp>
decltype(__cccl_internal::__cccl_declval<_Tp>(0)) __cccl_declval() noexcept;

// This requires a type to be implicitly convertible (also non-arithmetic)
template <class _Tp>
void __cccl_accepts_implicit_conversion(_Tp) noexcept;
#endif // no CUDA compilation

template <class...>
using __cccl_void_t = void;

template <class _Dest, class _Source, class = void>
struct __is_non_narrowing_convertible
{
static constexpr bool value = false;
};

// This also prohibits narrowing conversion in case of arithmetic types
template <class _Dest, class _Source>
struct __is_non_narrowing_convertible<_Dest,
_Source,
__cccl_void_t<decltype(__cccl_internal::__cccl_accepts_implicit_conversion<_Dest>(
__cccl_internal::__cccl_declval<_Source>())),
decltype(_Dest{__cccl_internal::__cccl_declval<_Source>()})>>
{
static constexpr bool value = true;
};

} // namespace __cccl_internal

#endif // __CCCL_IS_NON_NARROWING_CONVERTIBLE_H
1 change: 1 addition & 0 deletions libcudacxx/include/cuda/std/__cccl/system_header.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#define __CCCL_SYSTEM_HEADER_H

#include <cuda/std/__cccl/compiler.h>
#include <cuda/std/__cccl/is_non_narrowing_convertible.h> // IWYU pragma: export

// Enforce that cccl headers are treated as system headers
#if defined(_CCCL_COMPILER_GCC) || defined(_CCCL_COMPILER_NVHPC) || defined(_CCCL_COMPILER_ICC)
Expand Down
51 changes: 31 additions & 20 deletions libcudacxx/include/cuda/std/__complex/nvbf16.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,41 +41,52 @@ _CCCL_DIAG_POP
# include <sstream> // for std::basic_ostringstream
# endif // !_CCCL_COMPILER_NVRTC

_LIBCUDACXX_BEGIN_NAMESPACE_STD

// This is a workaround against the user defining macros __CUDA_NO_HALF_CONVERSIONS__ __CUDA_NO_HALF_OPERATORS__
namespace __cccl_internal
{
template <>
struct __complex_alignment<__nv_bfloat16> : integral_constant<size_t, alignof(__nv_bfloat162)>
{};
struct __is_non_narrowing_convertible<__nv_bfloat16, float>
{
static constexpr bool value = true;
};

template <>
struct __type_to_vector<__nv_bfloat16>
struct __is_non_narrowing_convertible<__nv_bfloat16, double>
{
using __type = __nv_bfloat162;
static constexpr bool value = true;
};

template <>
struct __libcpp_complex_overload_traits<__nv_bfloat16, false, false>
struct __is_non_narrowing_convertible<float, __nv_bfloat16>
{
typedef __nv_bfloat16 _ValueType;
typedef complex<__nv_bfloat16> _ComplexType;
static constexpr bool value = true;
};

// This is a workaround against the user defining macros __CUDA_NO_BFLOAT16_CONVERSIONS__ __CUDA_NO_BFLOAT16_OPERATORS__
template <>
struct __complex_can_implicitly_construct<__nv_bfloat16, float> : true_type
{};
struct __is_non_narrowing_convertible<double, __nv_bfloat16>
{
static constexpr bool value = true;
};
} // namespace __cccl_internal

_LIBCUDACXX_BEGIN_NAMESPACE_STD

template <>
struct __complex_can_implicitly_construct<__nv_bfloat16, double> : true_type
struct __complex_alignment<__nv_bfloat16> : integral_constant<size_t, alignof(__nv_bfloat162)>
{};

template <>
struct __complex_can_implicitly_construct<float, __nv_bfloat16> : true_type
{};
struct __type_to_vector<__nv_bfloat16>
{
using __type = __nv_bfloat162;
};

template <>
struct __complex_can_implicitly_construct<double, __nv_bfloat16> : true_type
{};
struct __libcpp_complex_overload_traits<__nv_bfloat16, false, false>
{
typedef __nv_bfloat16 _ValueType;
typedef complex<__nv_bfloat16> _ComplexType;
};

template <class _Tp>
_LIBCUDACXX_HIDE_FROM_ABI __nv_bfloat16 __convert_to_bfloat16(const _Tp& __value) noexcept
Expand Down Expand Up @@ -108,14 +119,14 @@ class _CCCL_TYPE_VISIBILITY_DEFAULT _CCCL_ALIGNAS(alignof(__nv_bfloat162)) compl
: __repr_(__re, __im)
{}

template <class _Up, __enable_if_t<__complex_can_implicitly_construct<value_type, _Up>::value, int> = 0>
template <class _Up, __enable_if_t<__cccl_internal::__is_non_narrowing_convertible<value_type, _Up>::value, int> = 0>
_LIBCUDACXX_HIDE_FROM_ABI complex(const complex<_Up>& __c)
: __repr_(__convert_to_bfloat16(__c.real()), __convert_to_bfloat16(__c.imag()))
{}

template <class _Up,
__enable_if_t<!__complex_can_implicitly_construct<value_type, _Up>::value, int> = 0,
__enable_if_t<_CCCL_TRAIT(is_constructible, value_type, _Up), int> = 0>
__enable_if_t<!__cccl_internal::__is_non_narrowing_convertible<value_type, _Up>::value, int> = 0,
__enable_if_t<_CCCL_TRAIT(is_constructible, value_type, _Up), int> = 0>
_LIBCUDACXX_HIDE_FROM_ABI explicit complex(const complex<_Up>& __c)
: __repr_(__convert_to_bfloat16(__c.real()), __convert_to_bfloat16(__c.imag()))
{}
Expand Down
51 changes: 31 additions & 20 deletions libcudacxx/include/cuda/std/__complex/nvfp16.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,41 +38,52 @@
# include <sstream> // for std::basic_ostringstream
# endif // !_CCCL_COMPILER_NVRTC

_LIBCUDACXX_BEGIN_NAMESPACE_STD

// This is a workaround against the user defining macros __CUDA_NO_HALF_CONVERSIONS__ __CUDA_NO_HALF_OPERATORS__
namespace __cccl_internal
{
template <>
struct __complex_alignment<__half> : integral_constant<size_t, alignof(__half2)>
{};
struct __is_non_narrowing_convertible<__half, float>
{
static constexpr bool value = true;
};

template <>
struct __type_to_vector<__half>
struct __is_non_narrowing_convertible<__half, double>
{
using __type = __half2;
static constexpr bool value = true;
};

template <>
struct __libcpp_complex_overload_traits<__half, false, false>
struct __is_non_narrowing_convertible<float, __half>
{
typedef __half _ValueType;
typedef complex<__half> _ComplexType;
static constexpr bool value = true;
};

// This is a workaround against the user defining macros __CUDA_NO_HALF_CONVERSIONS__ __CUDA_NO_HALF_OPERATORS__
template <>
struct __complex_can_implicitly_construct<__half, float> : true_type
{};
struct __is_non_narrowing_convertible<double, __half>
{
static constexpr bool value = true;
};
} // namespace __cccl_internal

_LIBCUDACXX_BEGIN_NAMESPACE_STD

template <>
struct __complex_can_implicitly_construct<__half, double> : true_type
struct __complex_alignment<__half> : integral_constant<size_t, alignof(__half2)>
{};

template <>
struct __complex_can_implicitly_construct<float, __half> : true_type
{};
struct __type_to_vector<__half>
{
using __type = __half2;
};

template <>
struct __complex_can_implicitly_construct<double, __half> : true_type
{};
struct __libcpp_complex_overload_traits<__half, false, false>
{
typedef __half _ValueType;
typedef complex<__half> _ComplexType;
};

template <class _Tp>
_LIBCUDACXX_HIDE_FROM_ABI __half __convert_to_half(const _Tp& __value) noexcept
Expand Down Expand Up @@ -105,14 +116,14 @@ class _CCCL_TYPE_VISIBILITY_DEFAULT _CCCL_ALIGNAS(alignof(__half2)) complex<__ha
: __repr_(__re, __im)
{}

template <class _Up, __enable_if_t<__complex_can_implicitly_construct<value_type, _Up>::value, int> = 0>
template <class _Up, __enable_if_t<__cccl_internal::__is_non_narrowing_convertible<value_type, _Up>::value, int> = 0>
_LIBCUDACXX_HIDE_FROM_ABI complex(const complex<_Up>& __c)
: __repr_(__convert_to_half(__c.real()), __convert_to_half(__c.imag()))
{}

template <class _Up,
__enable_if_t<!__complex_can_implicitly_construct<value_type, _Up>::value, int> = 0,
__enable_if_t<_CCCL_TRAIT(is_constructible, value_type, _Up), int> = 0>
__enable_if_t<!__cccl_internal::__is_non_narrowing_convertible<value_type, _Up>::value, int> = 0,
__enable_if_t<_CCCL_TRAIT(is_constructible, value_type, _Up), int> = 0>
_LIBCUDACXX_HIDE_FROM_ABI explicit complex(const complex<_Up>& __c)
: __repr_(__convert_to_half(__c.real()), __convert_to_half(__c.imag()))
{}
Expand Down
9 changes: 0 additions & 9 deletions libcudacxx/include/cuda/std/__complex/vector_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,6 @@ struct __complex_alignment : integral_constant<size_t, 2 * sizeof(_Tp)>
# define _LIBCUDACXX_COMPLEX_ALIGNAS
#endif

template <class _Dest, class _Source, class = void>
struct __complex_can_implicitly_construct : false_type
{};

template <class _Dest, class _Source>
struct __complex_can_implicitly_construct<_Dest, _Source, void_t<decltype(_Dest{_CUDA_VSTD::declval<_Source>()})>>
: true_type
{};

template <class _Tp>
struct __type_to_vector;

Expand Down
6 changes: 3 additions & 3 deletions libcudacxx/include/cuda/std/detail/libcxx/include/complex
Original file line number Diff line number Diff line change
Expand Up @@ -296,15 +296,15 @@ public:
, __im_(__im)
{}

template <class _Up, __enable_if_t<__complex_can_implicitly_construct<_Tp, _Up>::value, int> = 0>
template <class _Up, __enable_if_t<__cccl_internal::__is_non_narrowing_convertible<_Tp, _Up>::value, int> = 0>
_LIBCUDACXX_HIDE_FROM_ABI constexpr complex(const complex<_Up>& __c)
: __re_(static_cast<_Tp>(__c.real()))
, __im_(static_cast<_Tp>(__c.imag()))
{}

template <class _Up,
__enable_if_t<!__complex_can_implicitly_construct<_Tp, _Up>::value, int> = 0,
__enable_if_t<_CCCL_TRAIT(is_constructible, _Tp, _Up), int> = 0>
__enable_if_t<!__cccl_internal::__is_non_narrowing_convertible<_Tp, _Up>::value, int> = 0,
__enable_if_t<_CCCL_TRAIT(is_constructible, _Tp, _Up), int> = 0>
_LIBCUDACXX_HIDE_FROM_ABI explicit constexpr complex(const complex<_Up>& __c)
: __re_(static_cast<_Tp>(__c.real()))
, __im_(static_cast<_Tp>(__c.imag()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@
// constexpr complex(const complex<float>&);
// };

#if defined(__clang__)
# define _CCCL_IMPLICIT_SYSTEM_HEADER_CLANG
#elif defined(_MSC_VER)
# define _CCCL_IMPLICIT_SYSTEM_HEADER_MSVC
#else
# define _CCCL_IMPLICIT_SYSTEM_HEADER_GCC
#endif

#include <cuda/std/cassert>
#include <cuda/std/complex>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@
// explicit constexpr complex(const complex<double>&);
// };

#if defined(__clang__)
# define _CCCL_IMPLICIT_SYSTEM_HEADER_CLANG
#elif defined(_MSC_VER)
# define _CCCL_IMPLICIT_SYSTEM_HEADER_MSVC
#else
# define _CCCL_IMPLICIT_SYSTEM_HEADER_GCC
#endif

#include <cuda/std/cassert>
#include <cuda/std/complex>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ __host__ __device__ TEST_CONSTEXPR_CXX14 bool test()
int main(int, char**)
{
test();
#if TEST_STD_VER >= 2014
#if TEST_STD_VER >= 2014 && (!defined(TEST_COMPILER_GCC) || __GNUC__ >= 7)
static_assert(test(), "");
#endif // TEST_STD_VER >= 2014
#endif // TEST_STD_VER >= 2014 && !gcc-6

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ __host__ __device__ TEST_CONSTEXPR_CXX14 bool test()
int main(int, char**)
{
test();
#if TEST_STD_VER >= 2014
#if TEST_STD_VER >= 2014 && (!defined(TEST_COMPILER_GCC) || __GNUC__ >= 7)
static_assert(test(), "");
#endif // TEST_STD_VER >= 2014
#endif // TEST_STD_VER >= 2014 && !gcc-6

return 0;
}
Loading