summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Ihlenfeldt <max@igalia.com>2024-02-12 16:26:09 +0000
committerKhem Raj <raj.khem@gmail.com>2024-02-13 09:29:37 -0800
commitb71a45630d19f210079f42f6394cdde65195fb84 (patch)
tree2c3c0436223c5517d93339dbb280a5031a3e3980
parent5170ec9cdfe215fcef146fa9142521bfad1d7d6c (diff)
downloadmeta-clang-nanbield.tar.gz
Backport "std::pointer_traits should be SFINAE-friendly"nanbield
E.g. meta-browser's Chromium recipe needs this for its 121 version update. Signed-off-by: Max Ihlenfeldt <max@igalia.com>
-rw-r--r--recipes-devtools/clang/clang/0035-libcxx-Implement-LWG3545-std-pointer_traits-should-be-.patch660
-rw-r--r--recipes-devtools/clang/common.inc1
2 files changed, 661 insertions, 0 deletions
diff --git a/recipes-devtools/clang/clang/0035-libcxx-Implement-LWG3545-std-pointer_traits-should-be-.patch b/recipes-devtools/clang/clang/0035-libcxx-Implement-LWG3545-std-pointer_traits-should-be-.patch
new file mode 100644
index 0000000..af86540
--- /dev/null
+++ b/recipes-devtools/clang/clang/0035-libcxx-Implement-LWG3545-std-pointer_traits-should-be-.patch
@@ -0,0 +1,660 @@
1From 4d11d353656c5c848ddb2c13112cf1c2f8c041c0 Mon Sep 17 00:00:00 2001
2From: Daniel Cheng <zetafunction+github@gmail.com>
3Date: Mon, 18 Sep 2023 05:46:59 -0700
4Subject: [PATCH] [libc++] Implement LWG3545: std::pointer_traits should be
5 SFINAE-friendly. (#65177)
6
7See https://wg21.link/LWG3545 for background and details.
8
9Differential Revision: https://reviews.llvm.org/D158922
10
11Upstream-Status: Backport [https://github.com/llvm/llvm-project/pull/65177]
12---
13 libcxx/docs/Status/Cxx23Issues.csv | 2 +-
14 libcxx/include/__memory/pointer_traits.h | 17 +-
15 .../contiguous_iterator.verify.cpp | 54 ----
16 ...to_address_without_pointer_traits.pass.cpp | 66 ++++
17 .../pointer.traits/difference_type.pass.cpp | 28 --
18 .../pointer.traits/element_type.pass.cpp | 28 --
19 .../memory/pointer.traits/pointer.pass.cpp | 35 ---
20 .../memory/pointer.traits/rebind.pass.cpp | 32 --
21 .../pointer.traits/types.compile.pass.cpp | 289 ++++++++++++++++++
22 9 files changed, 367 insertions(+), 184 deletions(-)
23 delete mode 100644 libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/contiguous_iterator.verify.cpp
24 create mode 100644 libcxx/test/std/utilities/memory/pointer.conversion/to_address_without_pointer_traits.pass.cpp
25 delete mode 100644 libcxx/test/std/utilities/memory/pointer.traits/difference_type.pass.cpp
26 delete mode 100644 libcxx/test/std/utilities/memory/pointer.traits/element_type.pass.cpp
27 delete mode 100644 libcxx/test/std/utilities/memory/pointer.traits/pointer.pass.cpp
28 delete mode 100644 libcxx/test/std/utilities/memory/pointer.traits/rebind.pass.cpp
29 create mode 100644 libcxx/test/std/utilities/memory/pointer.traits/types.compile.pass.cpp
30
31diff --git a/libcxx/docs/Status/Cxx23Issues.csv b/libcxx/docs/Status/Cxx23Issues.csv
32index 0cc06674bda3..dc96fb2e0b50 100644
33--- a/libcxx/docs/Status/Cxx23Issues.csv
34+++ b/libcxx/docs/Status/Cxx23Issues.csv
35@@ -190,7 +190,7 @@
36 "`3118 <https://wg21.link/LWG3118>`__","``fpos`` equality comparison unspecified", "November 2022","","",""
37 "`3177 <https://wg21.link/LWG3177>`__","Limit permission to specialize variable templates to program-defined types", "November 2022","|Nothing to do|","",""
38 "`3515 <https://wg21.link/LWG3515>`__","§[stacktrace.basic.nonmem]: ``operator<<`` should be less templatized", "November 2022","","",""
39-"`3545 <https://wg21.link/LWG3545>`__","``std::pointer_traits`` should be SFINAE-friendly", "November 2022","","",""
40+"`3545 <https://wg21.link/LWG3545>`__","``std::pointer_traits`` should be SFINAE-friendly", "November 2022","|Complete|","18.0",""
41 "`3569 <https://wg21.link/LWG3569>`__","``join_view`` fails to support ranges of ranges with non-default_initializable iterators", "November 2022","","","|ranges|"
42 "`3594 <https://wg21.link/LWG3594>`__","``inout_ptr`` — inconsistent ``release()`` in destructor", "November 2022","","",""
43 "`3597 <https://wg21.link/LWG3597>`__","Unsigned integer types don't model advanceable", "November 2022","","","|ranges|"
44diff --git a/libcxx/include/__memory/pointer_traits.h b/libcxx/include/__memory/pointer_traits.h
45index c33e7bd43f29..7617948ed76b 100644
46--- a/libcxx/include/__memory/pointer_traits.h
47+++ b/libcxx/include/__memory/pointer_traits.h
48@@ -35,7 +35,7 @@ template <class _Tp>
49 struct __has_element_type<_Tp, __void_t<typename _Tp::element_type> > : true_type {};
50
51 template <class _Ptr, bool = __has_element_type<_Ptr>::value>
52-struct __pointer_traits_element_type;
53+struct __pointer_traits_element_type {};
54
55 template <class _Ptr>
56 struct __pointer_traits_element_type<_Ptr, true>
57@@ -111,12 +111,14 @@ struct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, false>
58 typedef _Sp<_Up, _Args...> type;
59 };
60
61+template <class _Ptr, class = void>
62+struct __pointer_traits_impl {};
63+
64 template <class _Ptr>
65-struct _LIBCPP_TEMPLATE_VIS pointer_traits
66-{
67- typedef _Ptr pointer;
68- typedef typename __pointer_traits_element_type<pointer>::type element_type;
69- typedef typename __pointer_traits_difference_type<pointer>::type difference_type;
70+struct __pointer_traits_impl<_Ptr, __void_t<typename __pointer_traits_element_type<_Ptr>::type> > {
71+ typedef _Ptr pointer;
72+ typedef typename __pointer_traits_element_type<pointer>::type element_type;
73+ typedef typename __pointer_traits_difference_type<pointer>::type difference_type;
74
75 #ifndef _LIBCPP_CXX03_LANG
76 template <class _Up> using rebind = typename __pointer_traits_rebind<pointer, _Up>::type;
77@@ -133,6 +135,9 @@ public:
78 {return pointer::pointer_to(__r);}
79 };
80
81+template <class _Ptr>
82+struct _LIBCPP_TEMPLATE_VIS pointer_traits : __pointer_traits_impl<_Ptr> {};
83+
84 template <class _Tp>
85 struct _LIBCPP_TEMPLATE_VIS pointer_traits<_Tp*>
86 {
87diff --git a/libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/contiguous_iterator.verify.cpp b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/contiguous_iterator.verify.cpp
88deleted file mode 100644
89index 37c5ad9610a6..000000000000
90--- a/libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/contiguous_iterator.verify.cpp
91+++ /dev/null
92@@ -1,54 +0,0 @@
93-//===----------------------------------------------------------------------===//
94-//
95-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
96-// See https://llvm.org/LICENSE.txt for license information.
97-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
98-//
99-//===----------------------------------------------------------------------===//
100-
101-// UNSUPPORTED: c++03, c++11, c++14, c++17
102-
103-// This test checks that std::contiguous_iterator uses std::to_address, which is not SFINAE-friendly
104-// when the type is missing the `T::element_type` typedef.
105-
106-#include <iterator>
107-
108-#include <compare>
109-#include <cstddef>
110-
111-struct no_element_type {
112- typedef std::contiguous_iterator_tag iterator_category;
113- typedef int value_type;
114- typedef std::ptrdiff_t difference_type;
115- typedef int* pointer;
116- typedef int& reference;
117- typedef no_element_type self;
118-
119- no_element_type();
120-
121- reference operator*() const;
122- pointer operator->() const;
123- auto operator<=>(const self&) const = default;
124-
125- self& operator++();
126- self operator++(int);
127-
128- self& operator--();
129- self operator--(int);
130-
131- self& operator+=(difference_type n);
132- self operator+(difference_type n) const;
133- friend self operator+(difference_type n, self x);
134-
135- self& operator-=(difference_type n);
136- self operator-(difference_type n) const;
137- difference_type operator-(const self& n) const;
138-
139- reference operator[](difference_type n) const;
140-};
141-
142-void test() {
143- (void) std::contiguous_iterator<no_element_type>;
144- // expected-error@*:* {{implicit instantiation of undefined template}}
145- // expected-note@*:* {{to_address}}
146-}
147diff --git a/libcxx/test/std/utilities/memory/pointer.conversion/to_address_without_pointer_traits.pass.cpp b/libcxx/test/std/utilities/memory/pointer.conversion/to_address_without_pointer_traits.pass.cpp
148new file mode 100644
149index 000000000000..4d05c10e0fbd
150--- /dev/null
151+++ b/libcxx/test/std/utilities/memory/pointer.conversion/to_address_without_pointer_traits.pass.cpp
152@@ -0,0 +1,66 @@
153+//===----------------------------------------------------------------------===//
154+//
155+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
156+// See https://llvm.org/LICENSE.txt for license information.
157+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
158+//
159+//===----------------------------------------------------------------------===//
160+
161+// <memory>
162+
163+// UNSUPPORTED: c++03, c++11, c++14, c++17
164+
165+// template <class Ptr> constexpr auto to_address(const Ptr& p) noexcept;
166+// Should not require a specialization of pointer_traits for Ptr.
167+
168+#include <memory>
169+#include <type_traits>
170+#include <utility>
171+
172+struct IntPtr {
173+ constexpr int* operator->() const { return ptr; }
174+
175+ int* ptr;
176+};
177+
178+template <class T, bool>
179+struct TemplatedPtr {
180+ constexpr T* operator->() const { return ptr; }
181+
182+ T* ptr;
183+};
184+
185+template <template <class...> class Templ, class Ignore, class... Args>
186+struct is_valid_expansion_impl : std::false_type {};
187+
188+template <template <class...> class Templ, class... Args>
189+struct is_valid_expansion_impl<Templ, decltype((void)Templ<Args...>{}, 0), Args...> : std::true_type {};
190+
191+template <template <class...> class Templ, class... Args>
192+using is_valid_expansion = is_valid_expansion_impl<Templ, int, Args...>;
193+
194+template <class Ptr>
195+using TestToAddressCall = decltype(std::to_address(std::declval<Ptr>()));
196+
197+constexpr bool test() {
198+ int i = 0;
199+
200+ static_assert(std::to_address(IntPtr{nullptr}) == nullptr);
201+ static_assert(std::to_address(IntPtr{&i}) == &i);
202+
203+ bool b = false;
204+
205+ static_assert(std::to_address(TemplatedPtr<bool, true>{nullptr}) == nullptr);
206+ static_assert(std::to_address(TemplatedPtr<bool, true>{&b}) == &b);
207+
208+ static_assert(!is_valid_expansion<TestToAddressCall, int>::value);
209+ static_assert(is_valid_expansion<TestToAddressCall, IntPtr>::value);
210+ static_assert(is_valid_expansion<TestToAddressCall, TemplatedPtr<bool, true>>::value);
211+
212+ return true;
213+}
214+
215+int main(int, char**) {
216+ static_assert(test());
217+ return 0;
218+}
219diff --git a/libcxx/test/std/utilities/memory/pointer.traits/difference_type.pass.cpp b/libcxx/test/std/utilities/memory/pointer.traits/difference_type.pass.cpp
220deleted file mode 100644
221index 7546df902882..000000000000
222--- a/libcxx/test/std/utilities/memory/pointer.traits/difference_type.pass.cpp
223+++ /dev/null
224@@ -1,28 +0,0 @@
225-//===----------------------------------------------------------------------===//
226-//
227-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
228-// See https://llvm.org/LICENSE.txt for license information.
229-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
230-//
231-//===----------------------------------------------------------------------===//
232-
233-// <memory>
234-
235-// template <class T>
236-// struct pointer_traits<T*>
237-// {
238-// typedef ptrdiff_t difference_type;
239-// ...
240-// };
241-
242-#include <memory>
243-#include <type_traits>
244-
245-#include "test_macros.h"
246-
247-int main(int, char**)
248-{
249- static_assert((std::is_same<std::pointer_traits<double*>::difference_type, std::ptrdiff_t>::value), "");
250-
251- return 0;
252-}
253diff --git a/libcxx/test/std/utilities/memory/pointer.traits/element_type.pass.cpp b/libcxx/test/std/utilities/memory/pointer.traits/element_type.pass.cpp
254deleted file mode 100644
255index e4f11c28e29b..000000000000
256--- a/libcxx/test/std/utilities/memory/pointer.traits/element_type.pass.cpp
257+++ /dev/null
258@@ -1,28 +0,0 @@
259-//===----------------------------------------------------------------------===//
260-//
261-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
262-// See https://llvm.org/LICENSE.txt for license information.
263-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
264-//
265-//===----------------------------------------------------------------------===//
266-
267-// <memory>
268-
269-// template <class T>
270-// struct pointer_traits<T*>
271-// {
272-// typedef T element_type;
273-// ...
274-// };
275-
276-#include <memory>
277-#include <type_traits>
278-
279-#include "test_macros.h"
280-
281-int main(int, char**)
282-{
283- static_assert((std::is_same<std::pointer_traits<const short*>::element_type, const short>::value), "");
284-
285- return 0;
286-}
287diff --git a/libcxx/test/std/utilities/memory/pointer.traits/pointer.pass.cpp b/libcxx/test/std/utilities/memory/pointer.traits/pointer.pass.cpp
288deleted file mode 100644
289index 14054b3c4f65..000000000000
290--- a/libcxx/test/std/utilities/memory/pointer.traits/pointer.pass.cpp
291+++ /dev/null
292@@ -1,35 +0,0 @@
293-//===----------------------------------------------------------------------===//
294-//
295-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
296-// See https://llvm.org/LICENSE.txt for license information.
297-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
298-//
299-//===----------------------------------------------------------------------===//
300-
301-// <memory>
302-
303-// template <class Ptr>
304-// struct pointer_traits
305-// {
306-// typedef Ptr pointer;
307-// ...
308-// };
309-
310-#include <memory>
311-#include <type_traits>
312-
313-#include "test_macros.h"
314-
315-struct A
316-{
317- typedef short element_type;
318- typedef char difference_type;
319-};
320-
321-int main(int, char**)
322-{
323- static_assert((std::is_same<std::pointer_traits<A>::pointer, A>::value), "");
324- static_assert((std::is_same<std::pointer_traits<int*>::pointer, int*>::value), "");
325-
326- return 0;
327-}
328diff --git a/libcxx/test/std/utilities/memory/pointer.traits/rebind.pass.cpp b/libcxx/test/std/utilities/memory/pointer.traits/rebind.pass.cpp
329deleted file mode 100644
330index f64213c9b887..000000000000
331--- a/libcxx/test/std/utilities/memory/pointer.traits/rebind.pass.cpp
332+++ /dev/null
333@@ -1,32 +0,0 @@
334-//===----------------------------------------------------------------------===//
335-//
336-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
337-// See https://llvm.org/LICENSE.txt for license information.
338-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
339-//
340-//===----------------------------------------------------------------------===//
341-
342-// <memory>
343-
344-// template <class T>
345-// struct pointer_traits<T*>
346-// {
347-// template <class U> using rebind = U*;
348-// ...
349-// };
350-
351-#include <memory>
352-#include <type_traits>
353-
354-#include "test_macros.h"
355-
356-int main(int, char**)
357-{
358-#if TEST_STD_VER >= 11
359- static_assert((std::is_same<std::pointer_traits<int*>::rebind<double>, double*>::value), "");
360-#else
361- static_assert((std::is_same<std::pointer_traits<int*>::rebind<double>::other, double*>::value), "");
362-#endif
363-
364- return 0;
365-}
366diff --git a/libcxx/test/std/utilities/memory/pointer.traits/types.compile.pass.cpp b/libcxx/test/std/utilities/memory/pointer.traits/types.compile.pass.cpp
367new file mode 100644
368index 000000000000..19461508ca0f
369--- /dev/null
370+++ b/libcxx/test/std/utilities/memory/pointer.traits/types.compile.pass.cpp
371@@ -0,0 +1,289 @@
372+//===----------------------------------------------------------------------===//
373+//
374+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
375+// See https://llvm.org/LICENSE.txt for license information.
376+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
377+//
378+//===----------------------------------------------------------------------===//
379+
380+// <memory>
381+
382+// template <class Ptr>
383+// struct pointer_traits
384+// {
385+// <details>
386+// };
387+//
388+// template <class T>
389+// struct pointer_traits<T*>
390+// {
391+// using pointer = T*;
392+// using element_type = T;
393+// using difference_type = ptrdiff_t;
394+// template <class U> using rebind = U*;
395+// static constexpr pointer pointer_to(<details>) noexcept;
396+// ...
397+// };
398+
399+#include <memory>
400+#include <type_traits>
401+
402+#include "test_macros.h"
403+
404+template <typename... Ts>
405+struct VoidifyImpl {
406+ using type = void;
407+};
408+
409+template <typename... Ts>
410+using Voidify = typename VoidifyImpl<Ts...>::type;
411+
412+template <class T, class = void>
413+struct HasElementType : std::false_type {};
414+
415+template <class T>
416+struct HasElementType<T, Voidify<typename std::pointer_traits<T>::element_type> > : std::true_type {};
417+
418+template <class T, class = void>
419+struct HasPointerType : std::false_type {};
420+
421+template <class T>
422+struct HasPointerType<T, Voidify<typename std::pointer_traits<T>::pointer> > : std::true_type {};
423+
424+template <class T, class = void>
425+struct HasDifferenceType : std::false_type {};
426+
427+template <class T>
428+struct HasDifferenceType<T, Voidify<typename std::pointer_traits<T>::difference_type> > : std::true_type {};
429+
430+template <class T, class U, class = void>
431+struct HasRebind : std::false_type {};
432+
433+template <class T, class U>
434+struct HasRebind<T, U, Voidify<typename std::pointer_traits<T>::template rebind<U> > > : std::true_type {};
435+
436+template <class T, class = void>
437+struct HasPointerTo : std::false_type {};
438+
439+template <class T>
440+struct HasPointerTo<
441+ T,
442+ Voidify<decltype(std::pointer_traits<T>::pointer_to(
443+ std::declval<typename std::add_lvalue_reference<typename std::pointer_traits<T>::element_type>::type>()))> >
444+ : std::true_type {};
445+
446+struct Irrelevant;
447+
448+struct NotAPtr {};
449+
450+struct LongPtr {};
451+
452+int global_int;
453+
454+template <class T, class Arg>
455+struct TemplatedPtr;
456+
457+struct PtrWithElementType {
458+ using element_type = int;
459+ template <class U>
460+#if TEST_STD_VER >= 11
461+ using rebind = TemplatedPtr<U, Irrelevant>;
462+#else
463+ struct rebind {
464+ using other = TemplatedPtr<U, Irrelevant>;
465+ };
466+#endif
467+ static TEST_CONSTEXPR_CXX14 PtrWithElementType pointer_to(element_type&) { return {&global_int}; }
468+ int* ptr;
469+};
470+
471+template <class T, class Arg>
472+struct TemplatedPtr {
473+ template <class U, class = typename std::enable_if<std::is_same<long, U>::value>::type>
474+#if TEST_STD_VER >= 11
475+ using rebind = LongPtr;
476+#else
477+ struct rebind {
478+ using other = LongPtr;
479+ };
480+#endif
481+ static TEST_CONSTEXPR_CXX14 TemplatedPtr pointer_to(T&) { return {&global_int}; }
482+
483+ T* ptr;
484+};
485+
486+template <class T, class Arg>
487+struct TemplatedPtrWithElementType {
488+ using element_type = int;
489+#if TEST_STD_VER >= 11
490+ template <class U, class = typename std::enable_if<std::is_same<long, U>::value>::type>
491+ using rebind = LongPtr;
492+#else
493+ template <class U, class = typename std::enable_if<std::is_same<long, U>::value>::type>
494+ struct rebind {
495+ using other = LongPtr;
496+ };
497+#endif
498+ static TEST_CONSTEXPR_CXX14 TemplatedPtrWithElementType pointer_to(element_type&) { return {&global_int}; }
499+
500+ element_type* ptr;
501+};
502+
503+int main() {
504+ {
505+ using Ptr = NotAPtr;
506+ static_assert(!HasElementType<Ptr>::value, "");
507+ static_assert(!HasPointerType<Ptr>::value, "");
508+ static_assert(!HasDifferenceType<Ptr>::value, "");
509+ static_assert(!HasRebind<Ptr, long>::value, "");
510+ static_assert(!HasPointerTo<Ptr>::value, "");
511+ }
512+
513+ {
514+ using Ptr = int*;
515+
516+ static_assert(HasElementType<Ptr>::value, "");
517+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::element_type, int);
518+
519+ static_assert(HasPointerType<Ptr>::value, "");
520+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::pointer, Ptr);
521+
522+ static_assert(HasDifferenceType<Ptr>::value, "");
523+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::difference_type, ptrdiff_t);
524+
525+ static_assert(HasRebind<Ptr, long>::value, "");
526+#if TEST_STD_VER >= 11
527+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>, long*);
528+#else
529+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>::other, long*);
530+#endif
531+
532+ static_assert(HasPointerTo<Ptr>::value, "");
533+ int variable = 0;
534+ ASSERT_SAME_TYPE(decltype(std::pointer_traits<Ptr>::pointer_to(variable)), Ptr);
535+#if TEST_STD_VER >= 20
536+ static_assert(std::pointer_traits<Ptr>::pointer_to(variable) == &variable, "");
537+#endif
538+ }
539+
540+ {
541+ using Ptr = const int*;
542+
543+ static_assert(HasElementType<Ptr>::value, "");
544+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::element_type, const int);
545+
546+ static_assert(HasPointerType<Ptr>::value, "");
547+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::pointer, Ptr);
548+
549+ static_assert(HasDifferenceType<Ptr>::value, "");
550+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::difference_type, ptrdiff_t);
551+
552+ static_assert(HasRebind<Ptr, long>::value, "");
553+#if TEST_STD_VER >= 11
554+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>, long*);
555+#else
556+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>::other, long*);
557+#endif
558+
559+ static_assert(HasPointerTo<Ptr>::value, "");
560+ const int const_variable = 0;
561+ ASSERT_SAME_TYPE(decltype(std::pointer_traits<Ptr>::pointer_to(const_variable)), Ptr);
562+#if TEST_STD_VER >= 20
563+ static_assert(std::pointer_traits<Ptr>::pointer_to(const_variable) == &const_variable, "");
564+#endif
565+ int variable = 0;
566+ ASSERT_SAME_TYPE(decltype(std::pointer_traits<Ptr>::pointer_to(variable)), Ptr);
567+#if TEST_STD_VER >= 20
568+ static_assert(std::pointer_traits<Ptr>::pointer_to(variable) == &variable, "");
569+#endif
570+ }
571+
572+ {
573+ using Ptr = PtrWithElementType;
574+
575+ static_assert(HasElementType<Ptr>::value, "");
576+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::element_type, int);
577+
578+ static_assert(HasPointerType<Ptr>::value, "");
579+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::pointer, Ptr);
580+
581+ static_assert(HasDifferenceType<Ptr>::value, "");
582+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::difference_type, ptrdiff_t);
583+
584+ static_assert(HasRebind<Ptr, long>::value, "");
585+#if TEST_STD_VER >= 11
586+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>, TemplatedPtr<long, Irrelevant>);
587+#else
588+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>::other, TemplatedPtr<long, Irrelevant>);
589+#endif
590+
591+ static_assert(HasPointerTo<Ptr>::value, "");
592+ int ignored = 0;
593+ ASSERT_SAME_TYPE(decltype(std::pointer_traits<Ptr>::pointer_to(ignored)), Ptr);
594+#if TEST_STD_VER >= 20
595+ static_assert(std::pointer_traits<Ptr>::pointer_to(ignored).ptr == &global_int, "");
596+#endif
597+ }
598+
599+ {
600+ using Ptr = TemplatedPtr<int, Irrelevant>;
601+
602+ static_assert(HasElementType<Ptr>::value, "");
603+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::element_type, int);
604+
605+ static_assert(HasPointerType<Ptr>::value, "");
606+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::pointer, Ptr);
607+
608+ static_assert(HasDifferenceType<Ptr>::value, "");
609+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::difference_type, ptrdiff_t);
610+
611+ static_assert(HasRebind<Ptr, long>::value, "");
612+ static_assert(HasRebind<Ptr, long long>::value, "");
613+#if TEST_STD_VER >= 11
614+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>, LongPtr);
615+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long long>, TemplatedPtr<long long, Irrelevant>);
616+#else
617+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>::other, LongPtr);
618+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long long>::other, TemplatedPtr<long long, Irrelevant>);
619+#endif
620+
621+ static_assert(HasPointerTo<Ptr>::value, "");
622+ int ignored = 0;
623+ ASSERT_SAME_TYPE(decltype(std::pointer_traits<Ptr>::pointer_to(ignored)), Ptr);
624+#if TEST_STD_VER >= 20
625+ static_assert(std::pointer_traits<Ptr>::pointer_to(ignored).ptr == &global_int, "");
626+#endif
627+ }
628+
629+ {
630+ using Ptr = TemplatedPtrWithElementType<Irrelevant, Irrelevant>;
631+
632+ static_assert(HasElementType<Ptr>::value, "");
633+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::element_type, int);
634+
635+ static_assert(HasPointerType<Ptr>::value, "");
636+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::pointer, Ptr);
637+
638+ static_assert(HasDifferenceType<Ptr>::value, "");
639+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::difference_type, ptrdiff_t);
640+
641+ static_assert(HasRebind<Ptr, long>::value, "");
642+ static_assert(HasRebind<Ptr, long long>::value, "");
643+#if TEST_STD_VER >= 11
644+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>, LongPtr);
645+ ASSERT_SAME_TYPE(
646+ typename std::pointer_traits<Ptr>::rebind<long long>, TemplatedPtrWithElementType<long long, Irrelevant>);
647+#else
648+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long>::other, LongPtr);
649+ ASSERT_SAME_TYPE(typename std::pointer_traits<Ptr>::rebind<long long>::other,
650+ TemplatedPtrWithElementType<long long, Irrelevant>);
651+#endif
652+
653+ static_assert(HasPointerTo<Ptr>::value, "");
654+ int ignored = 0;
655+ ASSERT_SAME_TYPE(decltype(std::pointer_traits<Ptr>::pointer_to(ignored)), Ptr);
656+#if TEST_STD_VER >= 20
657+ static_assert(std::pointer_traits<Ptr>::pointer_to(ignored).ptr == &global_int, "");
658+#endif
659+ }
660+}
diff --git a/recipes-devtools/clang/common.inc b/recipes-devtools/clang/common.inc
index aaf7e7d..c004d16 100644
--- a/recipes-devtools/clang/common.inc
+++ b/recipes-devtools/clang/common.inc
@@ -43,6 +43,7 @@ SRC_URI = "\
43 file://0032-compiler-rt-Fix-stat-struct-s-size-for-O32-ABI.patch \ 43 file://0032-compiler-rt-Fix-stat-struct-s-size-for-O32-ABI.patch \
44 file://0033-compiler-rt-Undef-_TIME_BITS-along-with-_FILE_OFFSET.patch \ 44 file://0033-compiler-rt-Undef-_TIME_BITS-along-with-_FILE_OFFSET.patch \
45 file://0034-ToolChains-Gnu.cpp-ARMLibDirs-search-also-in-lib32.patch \ 45 file://0034-ToolChains-Gnu.cpp-ARMLibDirs-search-also-in-lib32.patch \
46 file://0035-libcxx-Implement-LWG3545-std-pointer_traits-should-be-.patch \
46 " 47 "
47# Fallback to no-PIE if not set 48# Fallback to no-PIE if not set
48GCCPIE ??= "" 49GCCPIE ??= ""