-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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
[Clang][libc++] Implement __is_nothrow_convertible and use it in libc++ #80436
Conversation
@llvm/pr-subscribers-libcxx @llvm/pr-subscribers-clang Author: Nikolas Klauser (philnik777) ChangesGCC 13 has implemented this builtin. Full diff: https://github.com/llvm/llvm-project/pull/80436.diff 5 Files Affected:
diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index c1420079f7511..e91156837290f 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1569,6 +1569,7 @@ The following type trait primitives are supported by Clang. Those traits marked
* ``__is_const`` (C++, Embarcadero)
* ``__is_constructible`` (C++, MSVC 2013)
* ``__is_convertible`` (C++, Embarcadero)
+* ``__is_nothrow_convertible`` (C++, GNU)
* ``__is_convertible_to`` (Microsoft):
Synonym for ``__is_convertible``.
* ``__is_destructible`` (C++, MSVC 2013)
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 9117e4376c371..23817cde7a935 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -567,6 +567,7 @@ TYPE_TRAIT_1(__is_unsigned, IsUnsigned, KEYCXX)
// Embarcadero Binary Type Traits
TYPE_TRAIT_2(__is_same, IsSame, KEYCXX)
TYPE_TRAIT_2(__is_convertible, IsConvertible, KEYCXX)
+TYPE_TRAIT_2(__is_nothrow_convertible, IsNothrowConvertible, KEYCXX)
ARRAY_TYPE_TRAIT(__array_rank, ArrayRank, KEYCXX)
ARRAY_TYPE_TRAIT(__array_extent, ArrayExtent, KEYCXX)
// Name for GCC 6 compatibility.
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 3a32754e5376e..246d2313e089f 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5779,7 +5779,8 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
return Self.Context.typesAreCompatible(Lhs, Rhs);
}
case BTT_IsConvertible:
- case BTT_IsConvertibleTo: {
+ case BTT_IsConvertibleTo:
+ case BTT_IsNothrowConvertible: {
// C++0x [meta.rel]p4:
// Given the following function prototype:
//
@@ -5840,7 +5841,13 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
return false;
ExprResult Result = Init.Perform(Self, To, Kind, FromPtr);
- return !Result.isInvalid() && !SFINAE.hasErrorOccurred();
+ if (Result.isInvalid() || SFINAE.hasErrorOccurred())
+ return false;
+
+ if (BTT != BTT_IsNothrowConvertible)
+ return true;
+
+ return Self.canThrow(Result.get()) == CT_Cannot;
}
case BTT_IsAssignable:
diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index c5d196a2590f8..5659594577111 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -2118,7 +2118,7 @@ struct IntWrapper
{
int value;
IntWrapper(int _value) : value(_value) {}
- operator int() const {
+ operator int() const noexcept {
return value;
}
};
@@ -2126,7 +2126,7 @@ struct IntWrapper
struct FloatWrapper
{
float value;
- FloatWrapper(float _value) : value(_value) {}
+ FloatWrapper(float _value) noexcept : value(_value) {}
FloatWrapper(const IntWrapper& obj)
: value(static_cast<float>(obj.value)) {}
operator float() const {
@@ -2149,6 +2149,18 @@ void is_convertible()
int t08[T(__is_convertible(float, FloatWrapper))];
}
+void is_nothrow_convertible()
+{
+ int t01[T(__is_nothrow_convertible(IntWrapper, IntWrapper))];
+ int t02[T(__is_nothrow_convertible(IntWrapper, const IntWrapper))];
+ int t03[T(__is_nothrow_convertible(IntWrapper, int))];
+ int t04[F(__is_nothrow_convertible(int, IntWrapper))];
+ int t05[F(__is_nothrow_convertible(IntWrapper, FloatWrapper))];
+ int t06[F(__is_nothrow_convertible(FloatWrapper, IntWrapper))];
+ int t07[F(__is_nothrow_convertible(FloatWrapper, float))];
+ int t08[T(__is_nothrow_convertible(float, FloatWrapper))];
+}
+
struct FromInt { FromInt(int); };
struct ToInt { operator int(); };
typedef void Function();
diff --git a/libcxx/include/__type_traits/is_nothrow_convertible.h b/libcxx/include/__type_traits/is_nothrow_convertible.h
index eda7a49d7224c..2f9b4f953c140 100644
--- a/libcxx/include/__type_traits/is_nothrow_convertible.h
+++ b/libcxx/include/__type_traits/is_nothrow_convertible.h
@@ -26,6 +26,16 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
+#if __has_builtin(__is_nothrow_convertible)
+
+template <class _Tp, class _Up>
+struct is_nothrow_convertible : bool_constant<__is_nothrow_convertible(_Tp, _Up)> {};
+
+template <class _Tp, class _Up>
+inline constexpr bool is_nothrow_convertible_v = __is_nothrow_convertible(_Tp, _Up);
+
+#else // __has_builtin(__is_nothrow_convertible)
+
template <typename _Tp>
void __test_noexcept(_Tp) noexcept;
@@ -43,6 +53,8 @@ struct is_nothrow_convertible
template <typename _Fm, typename _To>
inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<_Fm, _To>::value;
+#endif // __has_builtin(__is_nothrow_convertible)
+
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Front end changes looks good.
It would be nice to add a release note on the clang side
@@ -567,6 +567,7 @@ TYPE_TRAIT_1(__is_unsigned, IsUnsigned, KEYCXX) | |||
// Embarcadero Binary Type Traits | |||
TYPE_TRAIT_2(__is_same, IsSame, KEYCXX) | |||
TYPE_TRAIT_2(__is_convertible, IsConvertible, KEYCXX) | |||
TYPE_TRAIT_2(__is_nothrow_convertible, IsNothrowConvertible, KEYCXX) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to move __is_nothrow_convertible / __is_convertible / __is_same above the Embarcadero comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a bunch more type traits that aren't listed correctly anymore, so IMO an NFC patch that updates them all would be better.
dc3aafe
to
d210ffc
Compare
…++ (llvm#80436) GCC 13 has implemented this builtin.
GCC 13 has implemented this builtin.