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&) {} // FIXME: expected-note {{here}}
140 };
141
142 struct Derived : Base {
143 // FIXME: This should be accepted.
fooPR12564::Derived144 void foo(Derived& d) noexcept(noexcept(d.bar(d))) {} // expected-error {{cannot bind to a value of unrelated type}}
145 };
146 }
147
148 namespace rdar13473493 {
149 template <typename F>
150 class wrap
151 {
152 public:
153 template <typename... Args>
operator ()(Args &&...args) const154 auto operator()(Args&&... args) const -> decltype(wrapped(args...)) // expected-note{{candidate template ignored: substitution failure [with Args = <int>]: use of undeclared identifier 'wrapped'}}
155 {
156 return wrapped(args...);
157 }
158
159 private:
160 F wrapped;
161 };
162
test(wrap<int (*)(int)> w)163 void test(wrap<int (*)(int)> w) {
164 w(5); // expected-error{{no matching function for call to object of type 'wrap<int (*)(int)>'}}
165 }
166 }
167