1 // RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
2 
3 struct A {
4   int &f(int*);
5   float &f(int*) const noexcept;
6 
7   int *ptr;
8   auto g1() noexcept(noexcept(f(ptr))) -> decltype(f(this->ptr));
9   auto g2() const noexcept(noexcept(f((*this).ptr))) -> decltype(f(ptr));
10 };
11 
testA(A & a)12 void testA(A &a) {
13   int &ir = a.g1();
14   float &fr = a.g2();
15   static_assert(!noexcept(a.g1()), "exception-specification failure");
16   static_assert(noexcept(a.g2()), "exception-specification failure");
17 }
18 
19 struct B {
20   char g();
fB21   template<class T> auto f(T t) -> decltype(t + g())
22   { return t + g(); }
23 };
24 
25 template auto B::f(int t) -> decltype(t + g());
26 
27 template<typename T>
28 struct C {
29   int &f(T*);
30   float &f(T*) const noexcept;
31 
32   T* ptr;
33   auto g1() noexcept(noexcept(f(ptr))) -> decltype(f(ptr));
34   auto g2() const noexcept(noexcept(f(((this))->ptr))) -> decltype(f(ptr));
35   auto g3() noexcept(noexcept(f(this->ptr))) -> decltype(f((*this).ptr));
36   auto g4() const noexcept(noexcept(f(((this))->ptr))) -> decltype(f(this->ptr));
37   auto g5() noexcept(noexcept(this->f(ptr))) -> decltype(this->f(ptr));
38   auto g6() const noexcept(noexcept(this->f(((this))->ptr))) -> decltype(this->f(ptr));
39   auto g7() noexcept(noexcept(this->f(this->ptr))) -> decltype(this->f((*this).ptr));
40   auto g8() const noexcept(noexcept(this->f(((this))->ptr))) -> decltype(this->f(this->ptr));
41 };
42 
test_C(C<int> ci)43 void test_C(C<int> ci) {
44   int &ir = ci.g1();
45   float &fr = ci.g2();
46   int &ir2 = ci.g3();
47   float &fr2 = ci.g4();
48   int &ir3 = ci.g5();
49   float &fr3 = ci.g6();
50   int &ir4 = ci.g7();
51   float &fr4 = ci.g8();
52   static_assert(!noexcept(ci.g1()), "exception-specification failure");
53   static_assert(noexcept(ci.g2()), "exception-specification failure");
54   static_assert(!noexcept(ci.g3()), "exception-specification failure");
55   static_assert(noexcept(ci.g4()), "exception-specification failure");
56   static_assert(!noexcept(ci.g5()), "exception-specification failure");
57   static_assert(noexcept(ci.g6()), "exception-specification failure");
58   static_assert(!noexcept(ci.g7()), "exception-specification failure");
59   static_assert(noexcept(ci.g8()), "exception-specification failure");
60 }
61 
62 namespace PR14263 {
63   template<typename T> struct X {
64     void f();
65     T f() const;
66 
gPR14263::X67     auto g()       -> decltype(this->f()) { return f(); }
gPR14263::X68     auto g() const -> decltype(this->f()) { return f(); }
69   };
70   template struct X<int>;
71 }
72 
73 namespace PR10036 {
74   template <class I>
75   void
76   iter_swap(I x, I y) noexcept;
77 
78   template <class T>
79   class A
80   {
81     T t_;
82   public:
83     void swap(A& a) noexcept(noexcept(iter_swap(&t_, &a.t_)));
84   };
85 
test()86   void test() {
87     A<int> i, j;
88     i.swap(j);
89   }
90 }
91 
92 namespace PR15290 {
93   template<typename T>
94   class A {
95     T v_;
add_to_v(A & t)96     friend int add_to_v(A &t) noexcept(noexcept(v_ + 42))
97     {
98       return t.v_ + 42;
99     }
100   };
f()101   void f()
102   {
103     A<int> t;
104     add_to_v(t);
105   }
106 }
107 
108 namespace Static {
109   struct X1 {
110     int m;
111     // FIXME: This should be accepted.
112     static auto f() -> decltype(m); // expected-error{{'this' cannot be implicitly used in a static member function declaration}}
113     static auto g() -> decltype(this->m); // expected-error{{'this' cannot be used in a static member function declaration}}
114 
115     static int h();
116 
117     static int i() noexcept(noexcept(m + 2)); // expected-error{{'this' cannot be implicitly used in a static member function declaration}}
118   };
119 
h()120   auto X1::h() -> decltype(m) { return 0; } // expected-error{{'this' cannot be implicitly used in a static member function declaration}}
121 
122   template<typename T>
123   struct X2 {
124     int m;
125 
126     T f(T*);
127     static T f(int);
128 
gStatic::X2129     auto g(T x) -> decltype(f(x)) { return 0; }
130   };
131 
test_X2()132   void test_X2() {
133     X2<int>().g(0);
134   }
135 }
136 
137 namespace PR12564 {
138   struct Base {
barPR12564::Base139     void bar(Base&) {}
140   };
141 
142   struct Derived : Base {
fooPR12564::Derived143     void foo(Derived& d) noexcept(noexcept(d.bar(d))) {}
144   };
145 }
146 
147 namespace rdar13473493 {
148   template <typename F>
149   class wrap
150   {
151   public:
152     template <typename... Args>
operator ()(Args &&...args) const153     auto operator()(Args&&... args) const -> decltype(wrapped(args...)) // expected-note{{candidate template ignored: substitution failure [with Args = <int>]: member 'wrapped' used before its declaration}}
154     {
155       return wrapped(args...);
156     }
157 
158   private:
159     F wrapped;
160   };
161 
test(wrap<int (*)(int)> w)162   void test(wrap<int (*)(int)> w) {
163     w(5); // expected-error{{no matching function for call to object of type 'wrap<int (*)(int)>'}}
164   }
165 }
166