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:
f(T a)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:
z(T a)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 
test()24 void test()
25 {
26     B<int> b;
27     b.z(3);
28 }
29 
30 struct A2 {
fA231   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 {
fA340   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 {
fA448   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:
f()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:
z2()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 
foo()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:
foo(A<T> p)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 
main2()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:
f(int hWnd)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:
base_fun(void * p)179   bool base_fun(void* p) { return false; }  // expected-note {{must qualify identifier to find this declaration in dependent base class}}
operator T*() const180   operator T*() const { return 0; }
181 };
182 
183 template <class T>
184 class Container : public Base<T> {
185  public:
186   template <typename S>
operator =(const Container<S> & rhs)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 
f()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 {
fooPR16014::B207   int     foo() { return a; }           // expected-warning {{lookup into dependent bases}}
barPR16014::B208   int    *bar() { return &a; }          // expected-warning {{lookup into dependent bases}}
bazPR16014::B209   int     baz() { return T::a; }
quxPR16014::B210   int T::*qux() { return &T::a; }
stuffPR16014::B211   static int T::*stuff() { return &T::a; }
stuff1PR16014::B212   static int stuff1() { return T::sa; }
stuff2PR16014::B213   static int *stuff2() { return &T::sa; }
stuff3PR16014::B214   static int stuff3() { return sa; }    // expected-warning {{lookup into dependent bases}}
stuff4PR16014::B215   static int *stuff4() { return &sa; }  // expected-warning {{lookup into dependent bases}}
216 };
217 
218 template <typename T> struct C : T {
fooPR16014::C219   int     foo() { return b; }      // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
barPR16014::C220   int    *bar() { return &b; }     // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
bazPR16014::C221   int     baz() { return T::b; }   // expected-error {{no member named 'b' in 'PR16014::A'}}
quxPR16014::C222   int T::*qux() { return &T::b; }  // expected-error {{no member named 'b' in 'PR16014::A'}}
fuzPR16014::C223   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 {
fooPR16014::D::Inner232     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 {
fooPR19233::A246   void foo() {
247     ::undef(); // expected-error {{no member named 'undef' in the global namespace}}
248   }
barPR19233::A249   void bar() {
250     ::UndefClass::undef(); // expected-error {{no member named 'UndefClass' in the global namespace}}
251   }
bazPR19233::A252   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}}
foononmethod_missing_this::Derived271   auto foo(int j) -> decltype(y * j) { // expected-warning {{lookup into dependent bases}}
272     return y * j; // expected-warning {{lookup into dependent bases}}
273   }
barnonmethod_missing_this::Derived274   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.
NameFromBaseclassify_nontype_from_base::A332 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}}
lateSpecifiedFunclookup_in_function_contexts::B455   static auto lateSpecifiedFunc() -> decltype(NameFromBase()) {
456     return {};
457   }
458 
memberFunclookup_in_function_contexts::B459   static void memberFunc() {
460     NameFromBase x; // expected-warning {{lookup into dependent bases}}
461   }
462 
funcLocalClasslookup_in_function_contexts::B463   static void funcLocalClass() {
464     struct X {
465       NameFromBase x; // expected-warning {{lookup into dependent bases}}
466     } y;
467   }
468 
localClassMethodlookup_in_function_contexts::B469   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 
funcLambdalookup_in_function_contexts::B478   static void funcLambda() {
479     auto l = []() {
480       NameFromBase x; // expected-warning {{lookup into dependent bases}}
481     };
482     l();
483   }
484 
constexprFunclookup_in_function_contexts::B485   static constexpr int constexprFunc() {
486     NameFromBase x = {}; // expected-warning {{lookup into dependent bases}}
487     return sizeof(x);
488   }
489 
autoFunclookup_in_function_contexts::B490   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.
f()502 template <int N> int f() { return N; }
f()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>
f()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 {
memberPR23810::Template556   void member() {
557     f(); // expected-warning {{found via unqualified lookup into dependent bases}}
558   }
559 };
test()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 {
fooUseUnqualifiedTypeNames581   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>
out_of_line()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 }
634