1 // RUN: %clang_cc1 -std=c++17 -verify=cxx17,expected %s
2 // RUN: %clang_cc1 -std=c++17 -verify=cxx17,expected %s -DNO_CONSTEXPR
3 // RUN: %clang_cc1 -std=c++20 -verify=cxx20,expected %s
5 // RUN: %clang_cc1 -std=c++17 -verify=cxx17,expected %s -fexperimental-new-constant-interpreter -DNEW_INTERP
6 // RUN: %clang_cc1 -std=c++17 -verify=cxx17,expected %s -fexperimental-new-constant-interpreter -DNEW_INTERP -DNO_CONSTEXPR
7 // RUN: %clang_cc1 -std=c++20 -verify=cxx20,expected %s -fexperimental-new-constant-interpreter -DNEW_INTERP
11 #define CONSTEXPR constexpr
16 template<typename T
> CONSTEXPR T
&&move(T
&x
) {
17 static_assert(T::moveable
, "instantiated move"); // expected-error {{no member named 'moveable' in 'B'}}
18 // expected-error@-1 {{no member named 'moveable' in 'C'}}
19 // expected-error@-2 {{no member named 'moveable' in 'D'}}
20 return static_cast<T
&&>(x
);
23 // Unrelated move functions are not the builtin.
24 template<typename T
> CONSTEXPR
int move(T
, T
) { return 5; }
26 template<typename T
, bool Rref
> struct ref
{ using type
= T
&; };
27 template<typename T
> struct ref
<T
, true> { using type
= T
&&; };
29 template<typename T
> CONSTEXPR
auto move_if_noexcept(T
&x
) -> typename ref
<T
, noexcept(T(static_cast<T
&&>(x
)))>::type
{
30 static_assert(T::moveable
, "instantiated move_if_noexcept"); // expected-error {{no member named 'moveable' in 'B'}}
31 // expected-error@-1 {{no member named 'moveable' in 'D'}}
32 return static_cast<typename ref
<T
, noexcept(T(static_cast<T
&&>(x
)))>::type
>(x
);
35 template<typename T
> struct remove_reference
{ using type
= T
; };
36 template<typename T
> struct remove_reference
<T
&> { using type
= T
; };
37 template<typename T
> struct remove_reference
<T
&&> { using type
= T
; };
39 template<typename T
> struct is_lvalue_reference
{ static constexpr bool value
= false; };
40 template<typename T
> struct is_lvalue_reference
<T
&> { static constexpr bool value
= true; };
42 template<typename T
> CONSTEXPR T
&&forward(typename remove_reference
<T
>::type
&x
) {
43 static_assert(T::moveable
, "instantiated forward"); // expected-error {{no member named 'moveable' in 'B'}}
44 // expected-error@-1 {{no member named 'moveable' in 'C'}}
45 // expected-error@-2 {{no member named 'moveable' in 'D'}}
46 return static_cast<T
&&>(x
);
48 template<typename T
> CONSTEXPR T
&&forward(typename remove_reference
<T
>::type
&&x
) {
49 static_assert(!is_lvalue_reference
<T
>::value
, "should not forward rval as lval"); // expected-error {{static assertion failed}}
50 return static_cast<T
&&>(x
);
53 template <class T
> struct is_const
{ static constexpr bool value
= false; };
54 template <class T
> struct is_const
<const T
> { static constexpr bool value
= true; };
56 template <bool B
, class T
, class F
> struct conditional
{ using type
= T
; };
57 template <class T
, class F
> struct conditional
<false, T
, F
> { using type
= F
; };
59 template <class U
, class T
>
60 using CopyConst
= typename conditional
<
61 is_const
<remove_reference
<U
>>::value
,
64 template <class U
, class T
>
65 using OverrideRef
= typename conditional
<
66 is_lvalue_reference
<U
&&>::value
,
67 typename remove_reference
<T
>::type
&,
68 typename remove_reference
<T
>::type
&&>::type
;
70 template <class U
, class T
>
71 using ForwardLikeRetType
= OverrideRef
<U
&&, CopyConst
<U
, T
>>;
73 template <class U
, class T
>
74 CONSTEXPR
auto forward_like(T
&&t
) -> ForwardLikeRetType
<U
, T
> {
75 using TT
= typename remove_reference
<T
>::type
;
76 static_assert(TT::moveable
, "instantiated as_const"); // expected-error {{no member named 'moveable' in 'B'}}
77 // expected-error@-1 {{no member named 'moveable' in 'D'}}
78 return static_cast<ForwardLikeRetType
<U
, T
>>(t
);
81 template<typename T
> CONSTEXPR
const T
&as_const(T
&x
) {
82 static_assert(T::moveable
, "instantiated as_const"); // expected-error {{no member named 'moveable' in 'B'}}
83 // expected-error@-1 {{no member named 'moveable' in 'D'}}
87 template<typename T
> CONSTEXPR T
*addressof(T
&x
) {
88 static_assert(T::moveable
, "instantiated addressof"); // expected-error {{no member named 'moveable' in 'B'}}
89 // expected-error@-1 {{no member named 'moveable' in 'D'}}
90 return __builtin_addressof(x
);
93 template<typename T
> CONSTEXPR T
*__addressof(T
&x
) {
94 static_assert(T::moveable
, "instantiated __addressof"); // expected-error {{no member named 'moveable' in 'B'}}
95 // expected-error@-1 {{no member named 'moveable' in 'D'}}
96 return __builtin_addressof(x
);
100 // Note: this doesn't have a 'moveable' member. Instantiation of the above
101 // functions will fail if it's attempted.
103 constexpr bool f(A a
) { // #f
104 A
&&move
= std::move(a
); // #call
105 A
&&move_if_noexcept
= std::move_if_noexcept(a
);
106 A
&&forward1
= std::forward
<A
>(a
);
107 A
&forward2
= std::forward
<A
&>(a
);
108 const A
&as_const
= std::as_const(a
);
109 A
*addressof
= std::addressof(a
);
110 A
*addressof2
= std::__addressof(a
);
111 return &move
== &a
&& &move_if_noexcept
== &a
&&
112 &forward1
== &a
&& &forward2
== &a
&&
113 &as_const
== &a
&& addressof
== &a
&&
114 addressof2
== &a
&& std::move(a
, a
) == 5;
118 static_assert(f({}), "should be constexpr");
119 #elif !defined(NEW_INTERP)
120 // expected-error@#f {{never produces a constant expression}}
121 // expected-note@#call {{}}
124 A
&forward_rval_as_lval() {
125 std::forward
<A
&&>(A()); // expected-warning {{const attribute}}
126 return std::forward
<A
&>(A()); // expected-note {{instantiation of}} expected-warning {{returning reference}}
130 B
&&(*pMove
)(B
&) = std::move
; // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}
131 B
&&(*pMoveIfNoexcept
)(B
&) = &std::move_if_noexcept
; // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}
132 B
&&(*pForward
)(B
&) = &std::forward
<B
>; // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}
133 B
&&(*pForwardLike
)(B
&) = &std::forward_like
<int&&, B
&>; // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}
134 const B
&(*pAsConst
)(B
&) = &std::as_const
; // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}
135 B
*(*pAddressof
)(B
&) = &std::addressof
; // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}
136 B
*(*pUnderUnderAddressof
)(B
&) = &std::__addressof
; // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}
137 int (*pUnrelatedMove
)(B
, B
) = std::move
;
140 C
&&(&rMove
)(C
&) = std::move
; // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}
141 C
&&(&rForward
)(C
&) = std::forward
<C
>; // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}
142 int (&rUnrelatedMove
)(B
, B
) = std::move
;
144 void attribute_const() {
146 std::move(n
); // expected-warning {{ignoring return value}}
147 std::move_if_noexcept(n
); // expected-warning {{ignoring return value}}
148 std::forward
<int>(n
); // expected-warning {{ignoring return value}}
149 std::forward_like
<float&&>(n
); // expected-warning {{ignoring return value}}
150 std::addressof(n
); // expected-warning {{ignoring return value}}
151 std::__addressof(n
); // expected-warning {{ignoring return value}}
152 std::as_const(n
); // expected-warning {{ignoring return value}}
156 void* operator new(__SIZE_TYPE__
, D
&&(*)(D
&));
157 void* operator new(__SIZE_TYPE__
, D
*(*)(D
&));
158 void* operator new(__SIZE_TYPE__
, const D
&(*)(D
&));
161 void placement_new() {
162 new (std::move
<D
>) D
; // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}
163 new (std::move_if_noexcept
<D
>) D
; // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}
164 new (std::forward
<D
>) D
; // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}
165 new (std::forward_like
<D
>) D
; // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}
166 new (std::addressof
<D
>) D
; // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}
167 new (std::__addressof
<D
>) D
; // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}
168 new (std::as_const
<D
>) D
; // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}
172 template<typename T
> int &move(T
);
174 int bad_signature
= std::move(0); // expected-error {{unsupported signature for 'std::move<int>'}}