1// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++1y -fms-compatibility -fno-spell-checking -fsyntax-only -verify %s 2 3 4template <class T> 5class A { 6public: 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 11template <class T> 12class B : public A<T> { 13public: 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 21template class B<int>; // expected-note {{requested here}} 22template class B<char>; // expected-note {{requested here}} 23 24void test() 25{ 26 B<int> b; 27 b.z(3); 28} 29 30struct 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}; 36template void A2::f(int); 37 38template<class T0> 39struct A3 { 40 template<class T1> void f(T1) { 41 XX; //expected-error {{use of undeclared identifier 'XX'}} 42 } 43}; 44template void A3<int>::f(int); 45 46template<class T0> 47struct A4 { 48 void f(char) { 49 XX; //expected-error {{use of undeclared identifier 'XX'}} 50 } 51}; 52template class A4<int>; 53 54 55namespace lookup_dependent_bases_id_expr { 56 57template<class T> class A { 58public: 59 int var; 60}; 61 62 63template<class T> 64class B : public A<T> { 65public: 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 71template class B<int>; 72 73} 74 75 76 77namespace lookup_dependent_base_class_static_function { 78 79template <class T> 80class A { 81public: 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 87template <class T> 88class B : public A<T> { 89public: 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}; 95template class B<int>; // expected-note {{requested here}} 96 97} 98 99 100 101namespace lookup_dependent_base_class_default_argument { 102 103template<class T> 104class A { 105public: 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 110template<class T> 111class B : public A<T> { 112public: 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 117void 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 127namespace lookup_dependent_base_class_friend { 128 129template <class T> 130class B { 131public: 132 static void g(); // expected-note {{must qualify identifier to find this declaration in dependent base class}} 133}; 134 135template <class T> 136class A : public B<T> { 137public: 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 143int main2() 144{ 145 A<int> a; 146 foo(a); // expected-note {{requested here}} 147} 148 149} 150 151 152namespace lookup_dependent_base_no_typo_correction { 153 154class C { 155public: 156 int m_hWnd; 157}; 158 159template <class T> 160class A : public T { 161public: 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 167template class A<C>; 168 169} 170 171namespace PR12701 { 172 173class A {}; 174class B {}; 175 176template <class T> 177class 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 183template <class T> 184class 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 192void 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 200namespace PR16014 { 201 202struct A { 203 int a; 204 static int sa; 205}; 206template <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 218template <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 227template struct B<A>; 228template struct C<A>; // expected-note-re 1+ {{in instantiation of member function 'PR16014::C<PR16014::A>::{{.*}}' requested here}} 229 230template <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}; 239template struct D<A>; 240 241} 242 243namespace PR19233 { 244template <class T> 245struct 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 258struct B { void qux(); }; 259struct C : B { }; 260template struct A<C>; // No error! B is a base of A<C>, and qux is available. 261 262struct D { }; 263template struct A<D>; // expected-note {{in instantiation of member function 'PR19233::A<PR19233::D>::baz' requested here}} 264 265} 266 267namespace nonmethod_missing_this { 268template <typename T> struct Base { int y = 42; }; 269template <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}; 278template struct Derived<int>; 279} 280 281namespace typedef_in_base { 282template <typename T> struct A { typedef T NameFromBase; }; 283template <typename T> struct B : A<T> { 284 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}} 285}; 286static_assert(sizeof(B<int>) == 4, ""); 287} 288 289namespace struct_in_base { 290template <typename T> struct A { struct NameFromBase {}; }; 291template <typename T> struct B : A<T> { 292 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}} 293}; 294static_assert(sizeof(B<int>) == 1, ""); 295} 296 297namespace enum_in_base { 298template <typename T> struct A { enum NameFromBase { X }; }; 299template <typename T> struct B : A<T> { 300 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}} 301}; 302static_assert(sizeof(B<int>) == sizeof(A<int>::NameFromBase), ""); 303} 304 305namespace two_types_in_base { 306template <typename T> struct A { typedef T NameFromBase; }; // expected-note {{member found by ambiguous name lookup}} 307template <typename T> struct B { struct NameFromBase { T m; }; }; // expected-note {{member found by ambiguous name lookup}} 308template <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}; 311static_assert(sizeof(C<int>) != 0, ""); // expected-note {{in instantiation of template class 'two_types_in_base::C<int>' requested here}} 312} 313 314namespace type_and_decl_in_base { 315template <typename T> struct A { typedef T NameFromBase; }; 316template <typename T> struct B { static const T NameFromBase = 42; }; 317template <typename T> struct C : A<T>, B<T> { 318 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}} 319}; 320} 321 322namespace classify_type_from_base { 323template <typename T> struct A { struct NameFromBase {}; }; 324template <typename T> struct B : A<T> { 325 A<NameFromBase> m; // expected-warning {{found via unqualified lookup into dependent bases}} 326}; 327} 328 329namespace 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. 332template <typename T> struct A { void NameFromBase() {} }; 333template <void (*F)()> struct B { }; 334template <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 340namespace template_in_base { 341template <typename T> struct A { 342 template <typename U> struct NameFromBase { U x; }; 343}; 344template <typename T> struct B : A<T> { 345 // Correct form. 346 typename B::template NameFromBase<T> m; 347}; 348template <typename T> struct C : A<T> { 349 // Incorrect form. 350 NameFromBase<T> m; // expected-error {{unknown type name 'NameFromBase'}} 351 //expected-error@-1 {{expected member name or ';' after declaration specifiers}} 352}; 353} 354 355namespace type_in_inner_class_in_base { 356template <typename T> 357struct A { 358 struct B { typedef T NameFromBase; }; 359}; 360template <typename T> 361struct C : A<T>::B { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}} 362} 363 364namespace type_in_inner_template_class_in_base { 365template <typename T> 366struct A { 367 template <typename U> struct B { typedef U InnerType; }; 368}; 369template <typename T> 370struct C : A<T>::template B<T> { 371 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}} 372}; 373} 374 375namespace have_nondependent_base { 376template <typename T> 377struct A { 378 // Nothing, lookup should fail. 379}; 380template <typename T> 381struct B : A<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}} 382struct C : A<int> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}} 383} 384 385namespace type_in_base_of_dependent_base { 386struct A { typedef int NameFromBase; }; 387template <typename T> 388struct B : A {}; 389template <typename T> 390struct 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 393namespace type_in_second_dependent_base { 394template <typename T> 395struct A {}; 396template<typename T> 397struct B { typedef T NameFromBase; }; 398template <typename T> 399struct 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 402namespace type_in_second_non_dependent_base { 403struct A {}; 404struct B { typedef int NameFromBase; }; 405template<typename T> 406struct C : A, B {}; 407template <typename T> 408struct 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 411namespace type_in_virtual_base_of_dependent_base { 412template <typename T> 413struct A { typedef T NameFromBase; }; 414template <typename T> 415struct B : virtual A<T> {}; 416template <typename T> 417struct 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}} 418C<int> c; 419} 420 421namespace type_in_base_of_multiple_dependent_bases { 422template <typename T> 423struct A { typedef T NameFromBase; }; 424template <typename T> 425struct B : public A<T> {}; 426template <typename T> 427struct 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:}} 428C<int> c; // expected-note {{in instantiation of template class 'type_in_base_of_multiple_dependent_bases::C<int>' requested here}} 429} 430 431namespace type_in_dependent_base_of_non_dependent_type { 432template<typename T> struct A { typedef int NameFromBase; }; 433template<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}; 443template<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}; 446template<typename T> struct F : B<T>::C { 447 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}} 448}; 449} 450 451namespace lookup_in_function_contexts { 452template <typename T> struct A { typedef T NameFromBase; }; 453template <typename T> 454struct B : A<T> { 455 // expected-warning@+1 {{lookup into dependent bases}} 456 static auto lateSpecifiedFunc() -> decltype(NameFromBase()) { 457 return {}; 458 } 459 460 static void memberFunc() { 461 NameFromBase x; // expected-warning {{lookup into dependent bases}} 462 } 463 464 static void funcLocalClass() { 465 struct X { 466 NameFromBase x; // expected-warning {{lookup into dependent bases}} 467 } y; 468 } 469 470 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 479 static void funcLambda() { 480 auto l = []() { 481 NameFromBase x; // expected-warning {{lookup into dependent bases}} 482 }; 483 l(); 484 } 485 486 static constexpr int constexprFunc() { 487 NameFromBase x = {}; // expected-warning {{lookup into dependent bases}} 488 return sizeof(x); 489 } 490 491 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. 498template struct B<int>; 499} 500 501namespace function_template_deduction { 502// Overloaded function templates. 503template <int N> int f() { return N; } 504template <typename T> int f() { return sizeof(T); } 505 506// Dependent base class with type. 507template <typename T> 508struct A { typedef T NameFromBase; }; 509template <typename T> 510struct 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. 516template <typename T> struct C { enum { NameFromBase = 4 }; }; 517template <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 523namespace function_template_undef_impl { 524template<class T> 525void f() { 526 Undef::staticMethod(); // expected-error {{use of undeclared identifier 'Undef'}} 527 UndefVar.method(); // expected-error {{use of undeclared identifier 'UndefVar'}} 528} 529} 530 531namespace PR20716 { 532template <template <typename T> class A> 533struct B : A<int> 534{ 535 XXX x; // expected-error {{unknown type name}} 536}; 537 538template <typename T> 539struct C {}; 540 541template <typename T> 542using D = C<T>; 543 544template <typename T> 545struct E : D<T> 546{ 547 XXX x; // expected-error {{unknown type name}} 548}; 549} 550 551namespace PR23810 { 552void f(int); 553struct Base { 554 void f(); // expected-note{{must qualify identifier to find this declaration in dependent base class}} 555}; 556template <typename T> struct Template : T { 557 void member() { 558 f(); // expected-warning {{found via unqualified lookup into dependent bases}} 559 } 560}; 561void test() { 562 Template<Base> x; 563 x.member(); // expected-note{{requested here}} 564}; 565} 566 567namespace PR23823 { 568// Don't delay lookup in SFINAE context. 569template <typename T> decltype(g(T())) check(); // expected-note{{candidate template ignored: substitution failure [with T = int]: use of undeclared identifier 'g'}} 570decltype(check<int>()) x; // expected-error{{no matching function for call to 'check'}} 571 572void h(); 573template <typename T> decltype(h(T())) check2(); // expected-note{{candidate template ignored: substitution failure [with T = int]: no matching function for call to 'h'}} 574decltype(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. 580template <typename T> 581struct UseUnqualifiedTypeNames : T { 582 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}; 593template <typename T> 594void UseUnqualifiedTypeNames<T>::out_of_line() { 595 void *p = new TheType; // expected-warning {{unqualified lookup}} expected-error {{no type}} 596} 597struct Base { 598 typedef int IntegerType; 599 struct TheType { 600 int f1, f2; 601 }; 602}; 603template struct UseUnqualifiedTypeNames<Base>; 604struct BadBase { }; 605template struct UseUnqualifiedTypeNames<BadBase>; // expected-note-re 2 {{in instantiation {{.*}} requested here}} 606 607namespace partial_template_lookup { 608 609class Bar; 610class Spare; 611 612template <class T, class X = Bar> 613class FooTemplated; 614 615class FooBase { 616public: 617 typedef int BaseTypedef; 618}; 619 620// Partial template spec (unused) 621template <class T> 622class FooTemplated<T, Spare> {}; 623 624// Partial template spec (used) 625template <class T> 626class FooTemplated<T, Bar> : public FooBase {}; 627 628// Full template spec 629template <class T, class X> 630class FooTemplated : public FooTemplated<T, Bar> { 631public: 632 BaseTypedef Member; // expected-warning {{unqualified lookup}} 633}; 634} 635