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