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: 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: 15 void z(T a) 16 { 17 f(a); // expected-warning 2{{use of member 'f' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} 18 g(); // expected-warning 2{{use of member '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 25 void test() 26 { 27 B<int> b; 28 b.z(3); 29 } 30 31 struct A2 { 32 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 { 41 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 { 49 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: 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: 91 static void z2(){ 92 static_func(); // expected-warning {{use of member 'static_func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} 93 func(); // expected-warning {{use of member '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 member '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 member '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 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: 139 friend void foo(A<T> p){ 140 g(); // expected-warning {{use of member 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} 141 } 142 }; 143 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: 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: 180 bool base_fun(void* p) { return false; } // expected-note {{must qualify identifier to find this declaration in dependent base class}} 181 operator T*() const { return 0; } 182 }; 183 184 template <class T> 185 class Container : public Base<T> { 186 public: 187 template <typename S> 188 bool operator=(const Container<S>& rhs) { 189 return base_fun(rhs); // expected-warning {{use of member 'base_fun' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} 190 } 191 }; 192 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 { 208 int foo() { return a; } // expected-warning {{lookup into dependent bases}} 209 int *bar() { return &a; } // expected-warning {{lookup into dependent bases}} 210 int baz() { return T::a; } 211 int T::*qux() { return &T::a; } 212 static int T::*stuff() { return &T::a; } 213 static int stuff1() { return T::sa; } 214 static int *stuff2() { return &T::sa; } 215 static int stuff3() { return sa; } // expected-warning {{lookup into dependent bases}} 216 static int *stuff4() { return &sa; } // expected-warning {{lookup into dependent bases}} 217 }; 218 219 template <typename T> struct C : T { 220 int foo() { return b; } // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}} 221 int *bar() { return &b; } // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}} 222 int baz() { return T::b; } // expected-error {{no member named 'b' in 'PR16014::A'}} 223 int T::*qux() { return &T::b; } // expected-error {{no member named 'b' in 'PR16014::A'}} 224 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 { 233 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 { 247 void foo() { 248 ::undef(); // expected-error {{no member named 'undef' in the global namespace}} 249 } 250 void bar() { 251 ::UndefClass::undef(); // expected-error {{no member named 'UndefClass' in the global namespace}} 252 } 253 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}} 272 auto foo(int j) -> decltype(y * j) { // expected-warning {{lookup into dependent bases}} 273 return y * j; // expected-warning {{lookup into dependent bases}} 274 } 275 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 type 'int' found by ambiguous name lookup}} 308 template <typename T> struct B { struct NameFromBase { T m; }; }; // expected-note {{member type 'two_types_in_base::B<int>::NameFromBase' 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 member '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. 333 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 member '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 member '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 member '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 member '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 member '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 member '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 member '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 member '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}} 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. 498 template struct B<int>; 499 } 500 501 namespace function_template_deduction { 502 // Overloaded function templates. 503 template <int N> int f() { return N; } 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> 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 { 557 void member() { 558 f(); // expected-warning {{found via unqualified lookup into dependent bases}} 559 } 560 }; 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 { 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 }; 593 template <typename T> 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