brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.3 KiB · a2ae219 Raw
175 lines · cpp
1// RUN: %clang_cc1 -std=c++17 -verify=cxx17,expected %s2// RUN: %clang_cc1 -std=c++17 -verify=cxx17,expected %s -DNO_CONSTEXPR3// RUN: %clang_cc1 -std=c++20 -verify=cxx20,expected %s4//5// RUN: %clang_cc1 -std=c++17 -verify=cxx17,expected %s -fexperimental-new-constant-interpreter -DNEW_INTERP6// RUN: %clang_cc1 -std=c++17 -verify=cxx17,expected %s -fexperimental-new-constant-interpreter -DNEW_INTERP -DNO_CONSTEXPR7// RUN: %clang_cc1 -std=c++20 -verify=cxx20,expected %s -fexperimental-new-constant-interpreter -DNEW_INTERP8 9namespace std {10#ifndef NO_CONSTEXPR11#define CONSTEXPR constexpr12#else13#define CONSTEXPR14#endif15 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);21  }22 23  // Unrelated move functions are not the builtin.24  template<typename T> CONSTEXPR int move(T, T) { return 5; }25 26  template<typename T, bool Rref> struct ref { using type = T&; };27  template<typename T> struct ref<T, true> { using type = T&&; };28 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);33  }34 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; };38 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; };41 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);47  }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);51  }52 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; };55 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; };58 59  template <class U, class T>60  using CopyConst = typename conditional<61          is_const<remove_reference<U>>::value,62          const T, T>::type;63 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;69 70  template <class U, class T>71  using ForwardLikeRetType = OverrideRef<U &&, CopyConst<U, T>>;72 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);79  }80 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'}}84    return x;85  }86 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);91  }92 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);97  }98}99 100// Note: this doesn't have a 'moveable' member. Instantiation of the above101// functions will fail if it's attempted.102struct A {};103constexpr bool f(A a) { // #f104  A &&move = std::move(a); // #call105  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;115}116 117#ifndef NO_CONSTEXPR118static_assert(f({}), "should be constexpr");119#elif !defined(NEW_INTERP)120// expected-error@#f {{never produces a constant expression}}121// expected-note@#call {{}}122#endif123 124A &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}}127}128 129struct B {};130B &&(*pMove)(B&) = std::move;                            // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}131B &&(*pMoveIfNoexcept)(B&) = &std::move_if_noexcept;     // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}132B &&(*pForward)(B&) = &std::forward<B>;                  // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}133B &&(*pForwardLike)(B&) = &std::forward_like<int&&, B&>; // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}134const B &(*pAsConst)(B&) = &std::as_const;               // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}135B *(*pAddressof)(B&) = &std::addressof;                  // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}136B *(*pUnderUnderAddressof)(B&) = &std::__addressof;      // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}137int (*pUnrelatedMove)(B, B) = std::move;138 139struct C {};140C &&(&rMove)(C&) = std::move;          // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}141C &&(&rForward)(C&) = std::forward<C>; // cxx17-warning {{non-addressable}} cxx20-error {{non-addressable}} expected-note {{instantiation of}}142int (&rUnrelatedMove)(B, B) = std::move;143 144void attribute_const() {145  int n;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}}153}154 155struct D {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&));159};160 161void 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}}169}170 171namespace std {172  template<typename T> int &move(T);173}174int bad_signature = std::move(0); // expected-error {{unsupported signature for 'std::move<int>'}}175