1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
11 // UNSUPPORTED: c++03, c++11, c++14, c++17
13 // template <class T> constexpr T* to_address(T* p) noexcept;
14 // template <class Ptr> constexpr auto to_address(const Ptr& p) noexcept;
20 #include "test_macros.h"
25 using element_type
= Irrelevant
;
26 constexpr explicit P1(int *p
) : p_(p
) { }
27 constexpr int *operator->() const { return p_
; }
32 using element_type
= Irrelevant
;
33 constexpr explicit P2(int *p
) : p_(p
) { }
34 constexpr P1
operator->() const { return p_
; }
39 constexpr explicit P3(int *p
) : p_(p
) { }
44 struct std::pointer_traits
<P3
> {
45 static constexpr int *to_address(const P3
& p
) { return p
.p_
; }
49 constexpr explicit P4(int *p
) : p_(p
) { }
50 int *operator->() const; // should never be called
55 struct std::pointer_traits
<P4
> {
56 static constexpr int *to_address(const P4
& p
) { return p
.p_
; }
60 using element_type
= Irrelevant
;
61 int const* const& operator->() const;
67 struct std::pointer_traits
<P6
> {
68 static int const* const& to_address(const P6
&);
71 // Taken from a build breakage caused in Clang
73 template<typename T
> struct CanProxy
;
76 CanProxy
<T
> operator->() const { return CanProxy
<T
>(); }
80 const CanProxy
<T
> *operator->() const { return nullptr; }
87 using element_type
= Irrelevant
;
89 TEST_CONSTEXPR
FancyPtrA(T
*p
) : p_(p
) {}
91 TEST_CONSTEXPR T
*operator->() const { return p_
; }
96 TEST_CONSTEXPR
FancyPtrB(T
*p
) : p_(p
) {}
102 struct std::pointer_traits
<P8::FancyPtrB
<T
> > {
103 static TEST_CONSTEXPR T
*to_address(const P8::FancyPtrB
<T
>& p
) { return p
.p_
; }
107 template<class T
> struct Holder
{ T t
; };
110 constexpr bool test() {
112 ASSERT_NOEXCEPT(std::to_address(&i
));
113 assert(std::to_address(&i
) == &i
);
115 ASSERT_NOEXCEPT(std::to_address(p1
));
116 assert(std::to_address(p1
) == &i
);
118 ASSERT_NOEXCEPT(std::to_address(p2
));
119 assert(std::to_address(p2
) == &i
);
121 ASSERT_NOEXCEPT(std::to_address(p3
));
122 assert(std::to_address(p3
) == &i
);
124 ASSERT_NOEXCEPT(std::to_address(p4
));
125 assert(std::to_address(p4
) == &i
);
127 ASSERT_SAME_TYPE(decltype(std::to_address(std::declval
<int const*>())), int const*);
128 ASSERT_SAME_TYPE(decltype(std::to_address(std::declval
<P5
>())), int const*);
129 ASSERT_SAME_TYPE(decltype(std::to_address(std::declval
<P6
>())), int const*);
131 P7::CanQual
<int>* p7
= nullptr;
132 assert(std::to_address(p7
) == nullptr);
133 ASSERT_SAME_TYPE(decltype(std::to_address(p7
)), P7::CanQual
<int>*);
135 Holder
<Incomplete
> *p8_nil
= nullptr; // for C++03 compatibility
136 P8::FancyPtrA
<Holder
<Incomplete
> > p8a
= p8_nil
;
137 assert(std::to_address(p8a
) == p8_nil
);
138 ASSERT_SAME_TYPE(decltype(std::to_address(p8a
)), decltype(p8_nil
));
140 P8::FancyPtrB
<Holder
<Incomplete
> > p8b
= p8_nil
;
141 assert(std::to_address(p8b
) == p8_nil
);
142 ASSERT_SAME_TYPE(decltype(std::to_address(p8b
)), decltype(p8_nil
));
145 assert(std::to_address(p9
) == p9
);
146 ASSERT_SAME_TYPE(decltype(std::to_address(p9
)), int*);
148 const int p10
[2] = {};
149 assert(std::to_address(p10
) == p10
);
150 ASSERT_SAME_TYPE(decltype(std::to_address(p10
)), const int*);
152 int (*p11
)() = nullptr;
153 assert(std::to_address(&p11
) == &p11
);
154 ASSERT_SAME_TYPE(decltype(std::to_address(&p11
)), int(**)());
156 // See https://github.com/llvm/llvm-project/issues/67449
160 assert(std::to_address
<S
>(p
) == p
);
161 ASSERT_SAME_TYPE(decltype(std::to_address
<S
>(p
)), S
*);
167 int main(int, char**) {
169 static_assert(test());