150
|
1 // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++1y -fms-compatibility -fno-spell-checking -fsyntax-only -verify %s
|
|
2
|
|
3
|
|
4 template <class T>
|
|
5 class A {
|
|
6 public:
|
|
7 void f(T a) { }// expected-note 2{{must qualify identifier to find this declaration in dependent base class}}
|
|
8 void g();// expected-note 2{{must qualify identifier to find this declaration in dependent base class}}
|
|
9 };
|
|
10
|
|
11 template <class T>
|
|
12 class B : public A<T> {
|
|
13 public:
|
|
14 void z(T a)
|
|
15 {
|
|
16 f(a); // expected-warning 2{{use of identifier 'f' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
|
|
17 g(); // expected-warning 2{{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
|
|
18 }
|
|
19 };
|
|
20
|
|
21 template class B<int>; // expected-note {{requested here}}
|
|
22 template class B<char>; // expected-note {{requested here}}
|
|
23
|
|
24 void test()
|
|
25 {
|
|
26 B<int> b;
|
|
27 b.z(3);
|
|
28 }
|
|
29
|
|
30 struct A2 {
|
|
31 template<class T> void f(T) {
|
|
32 XX; //expected-error {{use of undeclared identifier 'XX'}}
|
|
33 A2::XX; //expected-error {{no member named 'XX' in 'A2'}}
|
|
34 }
|
|
35 };
|
|
36 template void A2::f(int);
|
|
37
|
|
38 template<class T0>
|
|
39 struct A3 {
|
|
40 template<class T1> void f(T1) {
|
|
41 XX; //expected-error {{use of undeclared identifier 'XX'}}
|
|
42 }
|
|
43 };
|
|
44 template void A3<int>::f(int);
|
|
45
|
|
46 template<class T0>
|
|
47 struct A4 {
|
|
48 void f(char) {
|
|
49 XX; //expected-error {{use of undeclared identifier 'XX'}}
|
|
50 }
|
|
51 };
|
|
52 template class A4<int>;
|
|
53
|
|
54
|
|
55 namespace lookup_dependent_bases_id_expr {
|
|
56
|
|
57 template<class T> class A {
|
|
58 public:
|
|
59 int var;
|
|
60 };
|
|
61
|
|
62
|
|
63 template<class T>
|
|
64 class B : public A<T> {
|
|
65 public:
|
|
66 void f() {
|
|
67 var = 3; // expected-warning {{use of undeclared identifier 'var'; unqualified lookup into dependent bases of class template 'B' is a Microsoft extension}}
|
|
68 }
|
|
69 };
|
|
70
|
|
71 template class B<int>;
|
|
72
|
|
73 }
|
|
74
|
|
75
|
|
76
|
|
77 namespace lookup_dependent_base_class_static_function {
|
|
78
|
|
79 template <class T>
|
|
80 class A {
|
|
81 public:
|
|
82 static void static_func();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
|
|
83 void func();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
|
|
84 };
|
|
85
|
|
86
|
|
87 template <class T>
|
|
88 class B : public A<T> {
|
|
89 public:
|
|
90 static void z2(){
|
|
91 static_func(); // expected-warning {{use of identifier 'static_func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
|
|
92 func(); // expected-warning {{use of identifier 'func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-error {{call to non-static member function without an object argument}}
|
|
93 }
|
|
94 };
|
|
95 template class B<int>; // expected-note {{requested here}}
|
|
96
|
|
97 }
|
|
98
|
|
99
|
|
100
|
|
101 namespace lookup_dependent_base_class_default_argument {
|
|
102
|
|
103 template<class T>
|
|
104 class A {
|
|
105 public:
|
|
106 static int f1(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
|
|
107 int f2(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
|
|
108 };
|
|
109
|
|
110 template<class T>
|
|
111 class B : public A<T> {
|
|
112 public:
|
|
113 void g1(int p = f1());// expected-warning {{use of identifier 'f1' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
|
|
114 void g2(int p = f2());// expected-warning {{use of identifier 'f2' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-error {{call to non-static member function without an object argument}}
|
|
115 };
|
|
116
|
|
117 void foo()
|
|
118 {
|
|
119 B<int> b;
|
|
120 b.g1(); // expected-note {{required here}}
|
|
121 b.g2(); // expected-note {{required here}}
|
|
122 }
|
|
123
|
|
124 }
|
|
125
|
|
126
|
|
127 namespace lookup_dependent_base_class_friend {
|
|
128
|
|
129 template <class T>
|
|
130 class B {
|
|
131 public:
|
|
132 static void g(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
|
|
133 };
|
|
134
|
|
135 template <class T>
|
|
136 class A : public B<T> {
|
|
137 public:
|
|
138 friend void foo(A<T> p){
|
|
139 g(); // expected-warning {{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
|
|
140 }
|
|
141 };
|
|
142
|
|
143 int main2()
|
|
144 {
|
|
145 A<int> a;
|
|
146 foo(a); // expected-note {{requested here}}
|
|
147 }
|
|
148
|
|
149 }
|
|
150
|
|
151
|
|
152 namespace lookup_dependent_base_no_typo_correction {
|
|
153
|
|
154 class C {
|
|
155 public:
|
|
156 int m_hWnd;
|
|
157 };
|
|
158
|
|
159 template <class T>
|
|
160 class A : public T {
|
|
161 public:
|
|
162 void f(int hWnd) {
|
|
163 m_hWnd = 1; // expected-warning {{use of undeclared identifier 'm_hWnd'; unqualified lookup into dependent bases of class template 'A' is a Microsoft extension}}
|
|
164 }
|
|
165 };
|
|
166
|
|
167 template class A<C>;
|
|
168
|
|
169 }
|
|
170
|
|
171 namespace PR12701 {
|
|
172
|
|
173 class A {};
|
|
174 class B {};
|
|
175
|
|
176 template <class T>
|
|
177 class Base {
|
|
178 public:
|
|
179 bool base_fun(void* p) { return false; } // expected-note {{must qualify identifier to find this declaration in dependent base class}}
|
|
180 operator T*() const { return 0; }
|
|
181 };
|
|
182
|
|
183 template <class T>
|
|
184 class Container : public Base<T> {
|
|
185 public:
|
|
186 template <typename S>
|
|
187 bool operator=(const Container<S>& rhs) {
|
|
188 return base_fun(rhs); // expected-warning {{use of identifier 'base_fun' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
|
|
189 }
|
|
190 };
|
|
191
|
|
192 void f() {
|
|
193 Container<A> text_provider;
|
|
194 Container<B> text_provider2;
|
|
195 text_provider2 = text_provider; // expected-note {{in instantiation of function template specialization}}
|
|
196 }
|
|
197
|
|
198 } // namespace PR12701
|
|
199
|
|
200 namespace PR16014 {
|
|
201
|
|
202 struct A {
|
|
203 int a;
|
|
204 static int sa;
|
|
205 };
|
|
206 template <typename T> struct B : T {
|
|
207 int foo() { return a; } // expected-warning {{lookup into dependent bases}}
|
|
208 int *bar() { return &a; } // expected-warning {{lookup into dependent bases}}
|
|
209 int baz() { return T::a; }
|
|
210 int T::*qux() { return &T::a; }
|
|
211 static int T::*stuff() { return &T::a; }
|
|
212 static int stuff1() { return T::sa; }
|
|
213 static int *stuff2() { return &T::sa; }
|
|
214 static int stuff3() { return sa; } // expected-warning {{lookup into dependent bases}}
|
|
215 static int *stuff4() { return &sa; } // expected-warning {{lookup into dependent bases}}
|
|
216 };
|
|
217
|
|
218 template <typename T> struct C : T {
|
|
219 int foo() { return b; } // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
|
|
220 int *bar() { return &b; } // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
|
|
221 int baz() { return T::b; } // expected-error {{no member named 'b' in 'PR16014::A'}}
|
|
222 int T::*qux() { return &T::b; } // expected-error {{no member named 'b' in 'PR16014::A'}}
|
|
223 int T::*fuz() { return &U::a; } // expected-error {{use of undeclared identifier 'U'}} \
|
|
224 // expected-warning {{unqualified lookup into dependent bases of class template 'C'}}
|
|
225 };
|
|
226
|
|
227 template struct B<A>;
|
|
228 template struct C<A>; // expected-note-re 1+ {{in instantiation of member function 'PR16014::C<PR16014::A>::{{.*}}' requested here}}
|
|
229
|
|
230 template <typename T> struct D : T {
|
|
231 struct Inner {
|
|
232 int foo() {
|
|
233 // FIXME: MSVC can find this in D's base T! Even worse, if ::sa exists,
|
|
234 // clang will use it instead.
|
|
235 return sa; // expected-error {{use of undeclared identifier 'sa'}}
|
|
236 }
|
|
237 };
|
|
238 };
|
|
239 template struct D<A>;
|
|
240
|
|
241 }
|
|
242
|
|
243 namespace PR19233 {
|
|
244 template <class T>
|
|
245 struct A : T {
|
|
246 void foo() {
|
|
247 ::undef(); // expected-error {{no member named 'undef' in the global namespace}}
|
|
248 }
|
|
249 void bar() {
|
|
250 ::UndefClass::undef(); // expected-error {{no member named 'UndefClass' in the global namespace}}
|
|
251 }
|
|
252 void baz() {
|
|
253 B::qux(); // expected-error {{use of undeclared identifier 'B'}} \
|
|
254 // expected-warning {{unqualified lookup into dependent bases of class template 'A'}}
|
|
255 }
|
|
256 };
|
|
257
|
|
258 struct B { void qux(); };
|
|
259 struct C : B { };
|
|
260 template struct A<C>; // No error! B is a base of A<C>, and qux is available.
|
|
261
|
|
262 struct D { };
|
|
263 template struct A<D>; // expected-note {{in instantiation of member function 'PR19233::A<PR19233::D>::baz' requested here}}
|
|
264
|
|
265 }
|
|
266
|
|
267 namespace nonmethod_missing_this {
|
|
268 template <typename T> struct Base { int y = 42; };
|
|
269 template <typename T> struct Derived : Base<T> {
|
|
270 int x = y; // expected-warning {{lookup into dependent bases}}
|
|
271 auto foo(int j) -> decltype(y * j) { // expected-warning {{lookup into dependent bases}}
|
|
272 return y * j; // expected-warning {{lookup into dependent bases}}
|
|
273 }
|
|
274 int bar() {
|
|
275 return [&] { return y; }(); // expected-warning {{lookup into dependent bases}}
|
|
276 }
|
|
277 };
|
|
278 template struct Derived<int>;
|
|
279 }
|
|
280
|
|
281 namespace typedef_in_base {
|
|
282 template <typename T> struct A { typedef T NameFromBase; };
|
|
283 template <typename T> struct B : A<T> {
|
|
284 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
|
|
285 };
|
|
286 static_assert(sizeof(B<int>) == 4, "");
|
|
287 }
|
|
288
|
|
289 namespace struct_in_base {
|
|
290 template <typename T> struct A { struct NameFromBase {}; };
|
|
291 template <typename T> struct B : A<T> {
|
|
292 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
|
|
293 };
|
|
294 static_assert(sizeof(B<int>) == 1, "");
|
|
295 }
|
|
296
|
|
297 namespace enum_in_base {
|
|
298 template <typename T> struct A { enum NameFromBase { X }; };
|
|
299 template <typename T> struct B : A<T> {
|
|
300 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
|
|
301 };
|
|
302 static_assert(sizeof(B<int>) == sizeof(A<int>::NameFromBase), "");
|
|
303 }
|
|
304
|
|
305 namespace two_types_in_base {
|
|
306 template <typename T> struct A { typedef T NameFromBase; }; // expected-note {{member found by ambiguous name lookup}}
|
|
307 template <typename T> struct B { struct NameFromBase { T m; }; }; // expected-note {{member found by ambiguous name lookup}}
|
|
308 template <typename T> struct C : A<T>, B<T> {
|
|
309 NameFromBase m; // expected-error {{member 'NameFromBase' found in multiple base classes of different types}} expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
|
|
310 };
|
|
311 static_assert(sizeof(C<int>) != 0, ""); // expected-note {{in instantiation of template class 'two_types_in_base::C<int>' requested here}}
|
|
312 }
|
|
313
|
|
314 namespace type_and_decl_in_base {
|
|
315 template <typename T> struct A { typedef T NameFromBase; };
|
|
316 template <typename T> struct B { static const T NameFromBase = 42; };
|
|
317 template <typename T> struct C : A<T>, B<T> {
|
|
318 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
|
|
319 };
|
|
320 }
|
|
321
|
|
322 namespace classify_type_from_base {
|
|
323 template <typename T> struct A { struct NameFromBase {}; };
|
|
324 template <typename T> struct B : A<T> {
|
|
325 A<NameFromBase> m; // expected-warning {{found via unqualified lookup into dependent bases}}
|
|
326 };
|
|
327 }
|
|
328
|
|
329 namespace classify_nontype_from_base {
|
|
330 // MSVC does not do lookup of non-type declarations from dependent template base
|
|
331 // classes. The extra lookup only applies to types.
|
|
332 template <typename T> struct A { void NameFromBase() {} };
|
|
333 template <void (*F)()> struct B { };
|
|
334 template <typename T> struct C : A<T> {
|
|
335 B<C::NameFromBase> a; // correct
|
|
336 B<NameFromBase> b; // expected-error {{use of undeclared identifier 'NameFromBase'}}
|
|
337 };
|
|
338 }
|
|
339
|
|
340 namespace template_in_base {
|
|
341 template <typename T> struct A {
|
|
342 template <typename U> struct NameFromBase { U x; };
|
|
343 };
|
|
344 template <typename T> struct B : A<T> {
|
|
345 // Correct form.
|
|
346 typename B::template NameFromBase<T> m;
|
|
347 };
|
|
348 template <typename T> struct C : A<T> {
|
|
349 // Incorrect form.
|
|
350 NameFromBase<T> m; // expected-error {{no template named 'NameFromBase'}}
|
|
351 };
|
|
352 }
|
|
353
|
|
354 namespace type_in_inner_class_in_base {
|
|
355 template <typename T>
|
|
356 struct A {
|
|
357 struct B { typedef T NameFromBase; };
|
|
358 };
|
|
359 template <typename T>
|
|
360 struct C : A<T>::B { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
|
|
361 }
|
|
362
|
|
363 namespace type_in_inner_template_class_in_base {
|
|
364 template <typename T>
|
|
365 struct A {
|
|
366 template <typename U> struct B { typedef U InnerType; };
|
|
367 };
|
|
368 template <typename T>
|
|
369 struct C : A<T>::template B<T> {
|
|
370 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
|
|
371 };
|
|
372 }
|
|
373
|
|
374 namespace have_nondependent_base {
|
|
375 template <typename T>
|
|
376 struct A {
|
|
377 // Nothing, lookup should fail.
|
|
378 };
|
|
379 template <typename T>
|
|
380 struct B : A<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
|
|
381 struct C : A<int> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
|
|
382 }
|
|
383
|
|
384 namespace type_in_base_of_dependent_base {
|
|
385 struct A { typedef int NameFromBase; };
|
|
386 template <typename T>
|
|
387 struct B : A {};
|
|
388 template <typename T>
|
|
389 struct C : B<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
|
|
390 }
|
|
391
|
|
392 namespace type_in_second_dependent_base {
|
|
393 template <typename T>
|
|
394 struct A {};
|
|
395 template<typename T>
|
|
396 struct B { typedef T NameFromBase; };
|
|
397 template <typename T>
|
|
398 struct D : A<T>, B<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
|
|
399 }
|
|
400
|
|
401 namespace type_in_second_non_dependent_base {
|
|
402 struct A {};
|
|
403 struct B { typedef int NameFromBase; };
|
|
404 template<typename T>
|
|
405 struct C : A, B {};
|
|
406 template <typename T>
|
|
407 struct D : C<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
|
|
408 }
|
|
409
|
|
410 namespace type_in_virtual_base_of_dependent_base {
|
|
411 template <typename T>
|
|
412 struct A { typedef T NameFromBase; };
|
|
413 template <typename T>
|
|
414 struct B : virtual A<T> {};
|
|
415 template <typename T>
|
|
416 struct C : B<T>, virtual A<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
|
|
417 C<int> c;
|
|
418 }
|
|
419
|
|
420 namespace type_in_base_of_multiple_dependent_bases {
|
|
421 template <typename T>
|
|
422 struct A { typedef T NameFromBase; };
|
|
423 template <typename T>
|
|
424 struct B : public A<T> {};
|
|
425 template <typename T>
|
|
426 struct C : B<T>, public A<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-warning {{direct base 'A<int>' is inaccessible due to ambiguity:}}
|
|
427 C<int> c; // expected-note {{in instantiation of template class 'type_in_base_of_multiple_dependent_bases::C<int>' requested here}}
|
|
428 }
|
|
429
|
|
430 namespace type_in_dependent_base_of_non_dependent_type {
|
|
431 template<typename T> struct A { typedef int NameFromBase; };
|
|
432 template<typename T> struct B : A<T> {
|
|
433 struct C;
|
|
434 template<typename TT>
|
|
435 struct D : C {
|
|
436 NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
|
|
437 };
|
|
438 struct E : C {
|
|
439 NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
|
|
440 };
|
|
441 };
|
|
442 template<typename T> struct B<T>::C : B {
|
|
443 NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
|
|
444 };
|
|
445 template<typename T> struct F : B<T>::C {
|
|
446 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
|
|
447 };
|
|
448 }
|
|
449
|
|
450 namespace lookup_in_function_contexts {
|
|
451 template <typename T> struct A { typedef T NameFromBase; };
|
|
452 template <typename T>
|
|
453 struct B : A<T> {
|
|
454 // expected-warning@+1 {{lookup into dependent bases}}
|
|
455 static auto lateSpecifiedFunc() -> decltype(NameFromBase()) {
|
|
456 return {};
|
|
457 }
|
|
458
|
|
459 static void memberFunc() {
|
|
460 NameFromBase x; // expected-warning {{lookup into dependent bases}}
|
|
461 }
|
|
462
|
|
463 static void funcLocalClass() {
|
|
464 struct X {
|
|
465 NameFromBase x; // expected-warning {{lookup into dependent bases}}
|
|
466 } y;
|
|
467 }
|
|
468
|
|
469 void localClassMethod() {
|
|
470 struct X {
|
|
471 void bar() {
|
|
472 NameFromBase m; // expected-warning {{lookup into dependent bases}}
|
|
473 }
|
|
474 } x;
|
|
475 x.bar();
|
|
476 }
|
|
477
|
|
478 static void funcLambda() {
|
|
479 auto l = []() {
|
|
480 NameFromBase x; // expected-warning {{lookup into dependent bases}}
|
|
481 };
|
|
482 l();
|
|
483 }
|
|
484
|
|
485 static constexpr int constexprFunc() {
|
|
486 NameFromBase x = {}; // expected-warning {{lookup into dependent bases}}
|
|
487 return sizeof(x);
|
|
488 }
|
|
489
|
|
490 static auto autoFunc() {
|
|
491 NameFromBase x; // expected-warning {{lookup into dependent bases}}
|
|
492 return x;
|
|
493 }
|
|
494 };
|
|
495
|
|
496 // Force us to parse the methods.
|
|
497 template struct B<int>;
|
|
498 }
|
|
499
|
|
500 namespace function_template_deduction {
|
|
501 // Overloaded function templates.
|
|
502 template <int N> int f() { return N; }
|
|
503 template <typename T> int f() { return sizeof(T); }
|
|
504
|
|
505 // Dependent base class with type.
|
|
506 template <typename T>
|
|
507 struct A { typedef T NameFromBase; };
|
|
508 template <typename T>
|
|
509 struct B : A<T> {
|
|
510 // expected-warning@+1 {{found via unqualified lookup into dependent bases}}
|
|
511 int x = f<NameFromBase>();
|
|
512 };
|
|
513
|
|
514 // Dependent base class with enum.
|
|
515 template <typename T> struct C { enum { NameFromBase = 4 }; };
|
|
516 template <typename T> struct D : C<T> {
|
|
517 // expected-warning@+1 {{use of undeclared identifier 'NameFromBase'; unqualified lookup into dependent bases}}
|
|
518 int x = f<NameFromBase>();
|
|
519 };
|
|
520 }
|
|
521
|
|
522 namespace function_template_undef_impl {
|
|
523 template<class T>
|
|
524 void f() {
|
|
525 Undef::staticMethod(); // expected-error {{use of undeclared identifier 'Undef'}}
|
|
526 UndefVar.method(); // expected-error {{use of undeclared identifier 'UndefVar'}}
|
|
527 }
|
|
528 }
|
|
529
|
|
530 namespace PR20716 {
|
|
531 template <template <typename T> class A>
|
|
532 struct B : A<int>
|
|
533 {
|
|
534 XXX x; // expected-error {{unknown type name}}
|
|
535 };
|
|
536
|
|
537 template <typename T>
|
|
538 struct C {};
|
|
539
|
|
540 template <typename T>
|
|
541 using D = C<T>;
|
|
542
|
|
543 template <typename T>
|
|
544 struct E : D<T>
|
|
545 {
|
|
546 XXX x; // expected-error {{unknown type name}}
|
|
547 };
|
|
548 }
|
|
549
|
|
550 namespace PR23810 {
|
|
551 void f(int);
|
|
552 struct Base {
|
|
553 void f(); // expected-note{{must qualify identifier to find this declaration in dependent base class}}
|
|
554 };
|
|
555 template <typename T> struct Template : T {
|
|
556 void member() {
|
|
557 f(); // expected-warning {{found via unqualified lookup into dependent bases}}
|
|
558 }
|
|
559 };
|
|
560 void test() {
|
|
561 Template<Base> x;
|
|
562 x.member(); // expected-note{{requested here}}
|
|
563 };
|
|
564 }
|
|
565
|
|
566 namespace PR23823 {
|
|
567 // Don't delay lookup in SFINAE context.
|
|
568 template <typename T> decltype(g(T())) check(); // expected-note{{candidate template ignored: substitution failure [with T = int]: use of undeclared identifier 'g'}}
|
|
569 decltype(check<int>()) x; // expected-error{{no matching function for call to 'check'}}
|
|
570
|
|
571 void h();
|
|
572 template <typename T> decltype(h(T())) check2(); // expected-note{{candidate template ignored: substitution failure [with T = int]: no matching function for call to 'h'}}
|
|
573 decltype(check2<int>()) y; // expected-error{{no matching function for call to 'check2'}}
|
|
574 }
|
|
575
|
|
576 // We also allow unqualified lookup into bases in contexts where the we know the
|
|
577 // undeclared identifier *must* be a type, such as a new expression or catch
|
|
578 // parameter type.
|
|
579 template <typename T>
|
|
580 struct UseUnqualifiedTypeNames : T {
|
|
581 void foo() {
|
|
582 void *P = new TheType; // expected-warning {{unqualified lookup}} expected-error {{no type}}
|
|
583 size_t x = __builtin_offsetof(TheType, f2); // expected-warning {{unqualified lookup}} expected-error {{no type}}
|
|
584 try {
|
|
585 } catch (TheType) { // expected-warning {{unqualified lookup}} expected-error {{no type}}
|
|
586 }
|
|
587 enum E : IntegerType { E0 = 42 }; // expected-warning {{unqualified lookup}} expected-error {{no type}}
|
|
588 _Atomic(TheType) a; // expected-warning {{unqualified lookup}} expected-error {{no type}}
|
|
589 }
|
|
590 void out_of_line();
|
|
591 };
|
|
592 template <typename T>
|
|
593 void UseUnqualifiedTypeNames<T>::out_of_line() {
|
|
594 void *p = new TheType; // expected-warning {{unqualified lookup}} expected-error {{no type}}
|
|
595 }
|
|
596 struct Base {
|
|
597 typedef int IntegerType;
|
|
598 struct TheType {
|
|
599 int f1, f2;
|
|
600 };
|
|
601 };
|
|
602 template struct UseUnqualifiedTypeNames<Base>;
|
|
603 struct BadBase { };
|
|
604 template struct UseUnqualifiedTypeNames<BadBase>; // expected-note-re 2 {{in instantiation {{.*}} requested here}}
|
|
605
|
|
606 namespace partial_template_lookup {
|
|
607
|
|
608 class Bar;
|
|
609 class Spare;
|
|
610
|
|
611 template <class T, class X = Bar>
|
|
612 class FooTemplated;
|
|
613
|
|
614 class FooBase {
|
|
615 public:
|
|
616 typedef int BaseTypedef;
|
|
617 };
|
|
618
|
|
619 // Partial template spec (unused)
|
|
620 template <class T>
|
|
621 class FooTemplated<T, Spare> {};
|
|
622
|
|
623 // Partial template spec (used)
|
|
624 template <class T>
|
|
625 class FooTemplated<T, Bar> : public FooBase {};
|
|
626
|
|
627 // Full template spec
|
|
628 template <class T, class X>
|
|
629 class FooTemplated : public FooTemplated<T, Bar> {
|
|
630 public:
|
|
631 BaseTypedef Member; // expected-warning {{unqualified lookup}}
|
|
632 };
|
|
633 }
|