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