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