1 | // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s |
2 | template<typename T, typename U> |
3 | struct X0 { |
4 | void f(T x, U y) { |
5 | (void)(x + y); // expected-error{{invalid operands}} |
6 | } |
7 | }; |
8 | |
9 | struct X1 { }; |
10 | |
11 | template struct X0<int, float>; |
12 | template struct X0<int*, int>; |
13 | template struct X0<int X1::*, int>; // expected-note{{instantiation of}} |
14 | |
15 | template<typename T> |
16 | struct X2 { |
17 | void f(T); |
18 | |
19 | T g(T x, T y) { |
20 | /* DeclStmt */; |
21 | T *xp = &x, &yr = y; // expected-error{{pointer to a reference}} |
22 | /* NullStmt */; |
23 | } |
24 | }; |
25 | |
26 | template struct X2<int>; |
27 | template struct X2<int&>; // expected-note{{instantiation of}} |
28 | |
29 | template<typename T> |
30 | struct X3 { |
31 | void f(T) { |
32 | Label: |
33 | T x; |
34 | goto Label; |
35 | } |
36 | }; |
37 | |
38 | template struct X3<int>; |
39 | |
40 | template <typename T> struct X4 { |
41 | T f() const { |
42 | return; // expected-error{{non-void function 'f' should return a value}} |
43 | } |
44 | |
45 | T g() const { |
46 | return 1; // expected-error{{void function 'g' should not return a value}} |
47 | } |
48 | }; |
49 | |
50 | template struct X4<void>; // expected-note{{in instantiation of}} |
51 | template struct X4<int>; // expected-note{{in instantiation of}} |
52 | |
53 | struct Incomplete; // expected-note 2{{forward declaration}} |
54 | |
55 | template<typename T> struct X5 { |
56 | T f() { } // expected-error{{incomplete result type}} |
57 | }; |
58 | void test_X5(X5<Incomplete> x5); // okay! |
59 | |
60 | template struct X5<Incomplete>; // expected-note{{instantiation}} |
61 | |
62 | template<typename T, typename U, typename V> struct X6 { |
63 | U f(T t, U u, V v) { |
64 | // IfStmt |
65 | if (t > 0) |
66 | return u; |
67 | else { |
68 | if (t < 0) |
69 | return v; // expected-error{{cannot initialize return object of type}} |
70 | } |
71 | |
72 | if (T x = t) { |
73 | t = x; |
74 | } |
75 | return v; // expected-error{{cannot initialize return object of type}} |
76 | } |
77 | }; |
78 | |
79 | struct ConvertibleToInt { |
80 | operator int() const; |
81 | }; |
82 | |
83 | template struct X6<ConvertibleToInt, float, char>; |
84 | template struct X6<bool, int, int*>; // expected-note{{instantiation}} |
85 | |
86 | template <typename T> struct X7 { |
87 | void f() { |
88 | void *v = this; |
89 | } |
90 | }; |
91 | |
92 | template struct X7<int>; |
93 | |
94 | template<typename T> struct While0 { |
95 | void f(T t) { |
96 | while (t) { |
97 | } |
98 | |
99 | while (T t2 = T()) ; |
100 | } |
101 | }; |
102 | |
103 | template struct While0<float>; |
104 | |
105 | template<typename T> struct Do0 { |
106 | void f(T t) { |
107 | do { |
108 | } while (t); // expected-error{{not contextually}} |
109 | } |
110 | }; |
111 | |
112 | struct NotConvertibleToBool { }; |
113 | template struct Do0<ConvertibleToInt>; |
114 | template struct Do0<NotConvertibleToBool>; // expected-note{{instantiation}} |
115 | |
116 | template<typename T> struct For0 { |
117 | void f(T f, T l) { |
118 | for (; f != l; ++f) { |
119 | if (*f) |
120 | continue; |
121 | else if (*f == 17) |
122 | break; |
123 | } |
124 | } |
125 | }; |
126 | |
127 | template struct For0<int*>; |
128 | |
129 | template<typename T> struct Member0 { |
130 | void f(T t) { |
131 | t; |
132 | t.f; |
133 | t->f; |
134 | |
135 | T* tp; |
136 | tp.f; // expected-error{{member reference base type 'T *' is not a structure or union}} |
137 | tp->f; |
138 | |
139 | this->f; |
140 | this.f; // expected-error{{member reference base type 'Member0<T> *' is not a structure or union}} |
141 | } |
142 | }; |
143 | |
144 | template<typename T, typename U> struct Switch0 { |
145 | U f(T value, U v0, U v1, U v2) { |
146 | switch (value) { |
147 | case 0: return v0; |
148 | |
149 | case 1: return v1; |
150 | |
151 | case 2: // fall through |
152 | |
153 | default: |
154 | return v2; |
155 | } |
156 | } |
157 | }; |
158 | |
159 | template struct Switch0<int, float>; |
160 | |
161 | template<typename T, int I1, int I2> struct Switch1 { |
162 | T f(T x, T y, T z) { |
163 | switch (x) { |
164 | case I1: return y; // expected-note{{previous}} |
165 | case I2: return z; // expected-error{{duplicate}} |
166 | default: return x; |
167 | } |
168 | } |
169 | }; |
170 | |
171 | template struct Switch1<int, 1, 2>; |
172 | template struct Switch1<int, 2, 2>; // expected-note{{instantiation}} |
173 | |
174 | template<typename T> struct IndirectGoto0 { |
175 | void f(T x) { |
176 | // FIXME: crummy error message below |
177 | goto *x; // expected-error{{incompatible}} |
178 | |
179 | prior: |
180 | T prior_label; |
181 | prior_label = &&prior; // expected-error{{assigning to 'int'}} |
182 | |
183 | T later_label; |
184 | later_label = &&later; // expected-error{{assigning to 'int'}} |
185 | |
186 | later: |
187 | (void)(1+1); |
188 | } |
189 | }; |
190 | |
191 | template struct IndirectGoto0<void*>; |
192 | template struct IndirectGoto0<int>; // expected-note{{instantiation}} |
193 | |
194 | template<typename T> struct TryCatch0 { |
195 | void f() { |
196 | try { |
197 | } catch (T t) { // expected-error{{incomplete type}} \ |
198 | // expected-error{{abstract class}} |
199 | } catch (...) { |
200 | } |
201 | } |
202 | }; |
203 | |
204 | struct Abstract { |
205 | virtual void foo() = 0; // expected-note{{pure virtual}} |
206 | }; |
207 | |
208 | template struct TryCatch0<int>; // okay |
209 | template struct TryCatch0<Incomplete*>; // expected-note{{instantiation}} |
210 | template struct TryCatch0<Abstract>; // expected-note{{instantiation}} |
211 | |
212 | // PR4383 |
213 | template<typename T> struct X; |
214 | template<typename T> struct Y : public X<T> { |
215 | Y& x() { return *this; } |
216 | }; |
217 | |
218 | // Make sure our assertions don't get too uppity. |
219 | namespace test0 { |
220 | template <class T> class A { void foo(T array[10]); }; |
221 | template class A<int>; |
222 | } |
223 | |
224 | namespace PR7016 { |
225 | template<typename T> void f() { T x = x; } |
226 | template void f<int>(); |
227 | } |
228 | |
229 | namespace PR9880 { |
230 | struct lua_State; |
231 | struct no_tag { char a; }; // (A) |
232 | struct yes_tag { long a; long b; }; // (A) |
233 | |
234 | template <typename T> |
235 | struct HasIndexMetamethod { |
236 | template <typename U> |
237 | static no_tag check(...); |
238 | template <typename U> |
239 | static yes_tag check(char[sizeof(&U::luaIndex)]); |
240 | enum { value = sizeof(check<T>(0)) == sizeof(yes_tag) }; |
241 | }; |
242 | |
243 | class SomeClass { |
244 | public: |
245 | int luaIndex(lua_State* L); |
246 | }; |
247 | |
248 | int i = HasIndexMetamethod<SomeClass>::value; |
249 | } |
250 | |