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