p5-cxx0x.cpp revision 840462670ba7a6bc26265a2306b35f2f0f01f51c
1// RUN: %clang_cc1 -std=c++11 -verify %s 2 3namespace std_example { 4 5template<class T> struct A { ~A() = delete; }; // expected-note {{deleted here}} 6template<class T> auto h() -> A<T>; 7template<class T> auto i(T) -> T; 8template<class T> auto f(T) -> decltype(i(h<T>())); // #1 9template<class T> auto f(T) -> void; // #2 10auto g() -> void { 11 f(42); // ok, calls #2, since #1 is not viable. 12} 13template<class T> auto q(T) -> decltype((h<T>())); 14void r() { 15 // Deduction against q succeeds, but results in a temporary which can't be 16 // destroyed. 17 q(42); // expected-error {{attempt to use a deleted function}} 18} 19 20} 21 22class PD { 23 friend struct A; 24 ~PD(); // expected-note 5{{here}} 25public: 26 typedef int n; 27}; 28struct DD { 29 ~DD() = delete; // expected-note 2{{here}} 30 typedef int n; 31}; 32 33struct A { 34 decltype(PD()) s; // ok 35 decltype(PD())::n n; // ok 36 decltype(DD()) *p = new decltype(DD()); // ok 37}; 38 39// Two errors here: one for the decltype, one for the variable. 40decltype( 41 PD(), // expected-error {{private destructor}} 42 PD()) pd1; // expected-error {{private destructor}} 43decltype(DD(), // expected-error {{deleted function}} 44 DD()) dd1; // expected-error {{deleted function}} 45decltype( 46 PD(), // expected-error {{temporary of type 'PD' has private destructor}} 47 0) pd2; 48 49decltype(((13, ((DD())))))::n dd_parens; // ok 50decltype(((((42)), PD())))::n pd_parens_comma; // ok 51 52// Ensure parens aren't stripped from a decltype node. 53extern decltype(PD()) pd_ref; // ok 54decltype((pd_ref)) pd_ref3 = pd_ref; // ok, PD & 55decltype(pd_ref) pd_ref2 = pd_ref; // expected-error {{private destructor}} 56 57namespace libcxx_example { 58 struct nat { 59 nat() = delete; 60 nat(const nat&) = delete; 61 nat &operator=(const nat&) = delete; 62 ~nat() = delete; 63 }; 64 struct any { 65 any(...); 66 }; 67 68 template<typename T, typename U> struct is_same { static const bool value = false; }; 69 template<typename T> struct is_same<T, T> { static const bool value = true; }; 70 71 template<typename T> T declval(); 72 73 void swap(int &a, int &b); 74 nat swap(any, any); 75 76 template<typename T> struct swappable { 77 typedef decltype(swap(declval<T&>(), declval<T&>())) type; 78 static const bool value = !is_same<type, nat>::value; 79 constexpr operator bool() const { return value; } 80 }; 81 82 static_assert(swappable<int>(), ""); 83 static_assert(!swappable<const int>(), ""); 84} 85 86namespace RequireCompleteType { 87 template<int N, bool OK> struct S { 88 static_assert(OK, "boom!"); // expected-error 2{{boom!}} 89 }; 90 91 template<typename T> T make(); 92 template<int N, bool OK> S<N, OK> make(); 93 void consume(...); 94 95 decltype(make<0, false>()) *p1; // ok 96 decltype((make<1, false>())) *p2; // ok 97 98 // A complete type is required here in order to detect an overloaded 'operator,'. 99 decltype(123, make<2, false>()) *p3; // expected-note {{here}} 100 101 decltype(consume(make<3, false>())) *p4; // expected-note {{here}} 102 103 decltype(make<decltype(make<4, false>())>()) *p5; // ok 104} 105 106namespace Overload { 107 DD operator+(PD &a, PD &b); 108 decltype(PD()) *pd_ptr; 109 decltype(*pd_ptr + *pd_ptr) *dd_ptr; // ok 110 111 decltype(0, *pd_ptr) pd_ref2 = pd_ref; // ok 112 DD operator,(int a, PD b); 113 decltype(0, *pd_ptr) *dd_ptr2; // expected-error {{private destructor}} 114} 115