Skip to content

Commit 34ee4af

Browse files
<type_traits>: Partially unblock P0466R5 for Clang (#5621)
Co-authored-by: Stephan T. Lavavej <[email protected]>
1 parent 64c0c4f commit 34ee4af

File tree

2 files changed

+40
-5
lines changed
  • stl/inc
  • tests/std/tests/P0466R5_layout_compatibility_and_pointer_interconvertibility_traits

2 files changed

+40
-5
lines changed

stl/inc/type_traits

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2017,21 +2017,34 @@ _NO_SPECIALIZATIONS_OF_TYPE_TRAITS constexpr bool is_nothrow_invocable_r_v =
20172017
#endif // _HAS_CXX17
20182018

20192019
#if _HAS_CXX20
2020-
#ifndef __clang__ // TRANSITION, LLVM-48860
2020+
#if !defined(__clang__) || defined(__EDG__) \
2021+
|| __clang_major__ >= 19 // TRANSITION, VSO-2397560 (RWC relying on ancient Clang)
20212022
_EXPORT_STD template <class _Ty1, class _Ty2>
20222023
struct _NO_SPECIALIZATIONS_OF_TYPE_TRAITS is_layout_compatible : bool_constant<__is_layout_compatible(_Ty1, _Ty2)> {};
20232024

20242025
_EXPORT_STD template <class _Ty1, class _Ty2>
20252026
_NO_SPECIALIZATIONS_OF_TYPE_TRAITS constexpr bool is_layout_compatible_v = __is_layout_compatible(_Ty1, _Ty2);
20262027

2028+
#if !defined(__clang__) || defined(__EDG__) // TRANSITION, LLVM-135273
20272029
_EXPORT_STD template <class _Base, class _Derived>
20282030
struct _NO_SPECIALIZATIONS_OF_TYPE_TRAITS is_pointer_interconvertible_base_of
20292031
: bool_constant<__is_pointer_interconvertible_base_of(_Base, _Derived)> {};
20302032

20312033
_EXPORT_STD template <class _Base, class _Derived>
20322034
_NO_SPECIALIZATIONS_OF_TYPE_TRAITS constexpr bool is_pointer_interconvertible_base_of_v =
20332035
__is_pointer_interconvertible_base_of(_Base, _Derived);
2036+
#else // ^^^ no workaround / workaround vvv
2037+
_EXPORT_STD template <class _Base, class _Derived>
2038+
struct _NO_SPECIALIZATIONS_OF_TYPE_TRAITS is_pointer_interconvertible_base_of
2039+
: bool_constant<__is_pointer_interconvertible_base_of(remove_cv_t<_Base>, remove_cv_t<_Derived>)> {};
2040+
2041+
_EXPORT_STD template <class _Base, class _Derived>
2042+
_NO_SPECIALIZATIONS_OF_TYPE_TRAITS constexpr bool is_pointer_interconvertible_base_of_v =
2043+
__is_pointer_interconvertible_base_of(remove_cv_t<_Base>, remove_cv_t<_Derived>);
2044+
#endif // ^^^ workaround ^^^
2045+
#endif // ^^^ no workaround ^^^
20342046

2047+
#ifndef __clang__ // TRANSITION, LLVM-48860
20352048
_EXPORT_STD template <class _ClassTy, class _MemberTy>
20362049
_NODISCARD _NO_SPECIALIZATIONS_OF_TYPE_TRAITS constexpr bool is_pointer_interconvertible_with_class(
20372050
_MemberTy _ClassTy::* _Pm) noexcept {

tests/std/tests/P0466R5_layout_compatibility_and_pointer_interconvertibility_traits/test.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ struct S { // Must be declared at namespace scope due to static data member
1414
};
1515

1616
constexpr bool test() {
17-
#if defined(__cpp_lib_is_layout_compatible) && defined(__cpp_lib_is_pointer_interconvertible) // TRANSITION, LLVM-48860
1817
// is_layout_compatible tests
1918
{
2019
struct S0 {
@@ -42,14 +41,28 @@ constexpr bool test() {
4241
int v1;
4342

4443
private:
44+
#ifdef __clang__
45+
#pragma clang diagnostic push
46+
#pragma clang diagnostic ignored "-Wunused-private-field"
47+
#endif // defined(__clang__)
4548
int v2;
49+
#ifdef __clang__
50+
#pragma clang diagnostic pop
51+
#endif // defined(__clang__)
4652
};
4753

4854
struct S5 {
4955
int v1;
5056

5157
private:
58+
#ifdef __clang__
59+
#pragma clang diagnostic push
60+
#pragma clang diagnostic ignored "-Wunused-private-field"
61+
#endif // defined(__clang__)
5262
int v2;
63+
#ifdef __clang__
64+
#pragma clang diagnostic pop
65+
#endif // defined(__clang__)
5366
};
5467

5568
enum E1 { e1, e2, e3, e4 };
@@ -94,13 +107,21 @@ constexpr bool test() {
94107
int : 0;
95108
};
96109
class D : public C {};
97-
// Disable warning C4408: anonymous union did not declare any data members
110+
#ifdef __clang__
111+
#pragma clang diagnostic push
112+
#pragma clang diagnostic ignored "-Wmissing-declarations"
113+
#else // ^^^ defined(__clang__) / !defined(__clang__) vvv
98114
#pragma warning(push)
99-
#pragma warning(disable : 4408)
115+
#pragma warning(disable : 4408) // C4408: anonymous union did not declare any data members
116+
#endif // ^^^ !defined(__clang__) ^^^
100117
class E : public A {
101118
union {};
102119
};
120+
#ifdef __clang__
121+
#pragma clang diagnostic pop
122+
#else // ^^^ defined(__clang__) / !defined(__clang__) vvv
103123
#pragma warning(pop)
124+
#endif // ^^^ !defined(__clang__) ^^^
104125
class F : private A {}; // Non-public inheritance
105126
class NS : public B, public C {}; // Non-standard layout
106127
class I; // Incomplete
@@ -134,6 +155,7 @@ constexpr bool test() {
134155
ASSERT(!is_pointer_interconvertible_base_of_v<U, I>);
135156
}
136157

158+
#ifndef __clang__ // TRANSITION, LLVM-48860
137159
// is_corresponding_member tests
138160
{
139161
struct S1 {
@@ -238,7 +260,7 @@ constexpr bool test() {
238260
ASSERT(!is_pointer_interconvertible_with_class(&C::f1));
239261
ASSERT(!is_pointer_interconvertible_with_class(static_cast<int A::*>(nullptr)));
240262
}
241-
#endif // ^^^ defined(__cpp_lib_is_layout_compatible) && defined(__cpp_lib_is_pointer_interconvertible) ^^^
263+
#endif // ^^^ no workaround ^^^
242264
return true;
243265
}
244266

0 commit comments

Comments
 (0)