p5-cxx0x.cpp revision 76f3f69db1416425070177243e9f390122c553e0
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 4{{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(PD(), PD()) pd1; // expected-error 2{{private destructor}} 41decltype(DD(), DD()) dd1; // expected-error 2{{deleted function}} 42 43decltype(((13, ((DD())))))::n dd_parens; // ok 44decltype(((((42)), PD())))::n pd_parens_comma; // ok 45 46// Ensure parens aren't stripped from a decltype node. 47extern decltype(PD()) pd_ref; // ok 48decltype((pd_ref)) pd_ref3 = pd_ref; // ok, PD & 49decltype(pd_ref) pd_ref2 = pd_ref; // expected-error {{private destructor}} 50 51namespace libcxx_example { 52 struct nat { 53 nat() = delete; 54 nat(const nat&) = delete; 55 nat &operator=(const nat&) = delete; 56 ~nat() = delete; 57 }; 58 struct any { 59 any(...); 60 }; 61 62 template<typename T, typename U> struct is_same { static const bool value = false; }; 63 template<typename T> struct is_same<T, T> { static const bool value = true; }; 64 65 template<typename T> T declval(); 66 67 void swap(int &a, int &b); 68 nat swap(any, any); 69 70 template<typename T> struct swappable { 71 typedef decltype(swap(declval<T&>(), declval<T&>())) type; 72 static const bool value = !is_same<type, nat>::value; 73 constexpr operator bool() { return value; } 74 }; 75 76 static_assert(swappable<int>(), ""); 77 static_assert(!swappable<const int>(), ""); 78} 79 80namespace RequireCompleteType { 81 template<int N, bool OK> struct S { 82 static_assert(OK, "boom!"); // expected-error 2{{boom!}} 83 }; 84 85 template<typename T> T make(); 86 template<int N, bool OK> S<N, OK> make(); 87 void consume(...); 88 89 decltype(make<0, false>()) *p1; // ok 90 decltype((make<1, false>())) *p2; // ok 91 92 // A complete type is required here in order to detect an overloaded 'operator,'. 93 decltype(123, make<2, false>()) *p3; // expected-note {{here}} 94 95 decltype(consume(make<3, false>())) *p4; // expected-note {{here}} 96 97 decltype(make<decltype(make<4, false>())>()) *p5; // ok 98} 99 100namespace Overload { 101 DD operator+(PD &a, PD &b); 102 decltype(PD()) *pd_ptr; 103 decltype(*pd_ptr + *pd_ptr) *dd_ptr; // ok 104 105 decltype(0, *pd_ptr) pd_ref2 = pd_ref; // ok 106 DD operator,(int a, PD b); 107 decltype(0, *pd_ptr) *dd_ptr2; // expected-error {{private destructor}} 108} 109