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