1 // RUN: %clang_cc1 -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 {{must qualify identifier to find this declaration in dependent base class}} 8 void g();// expected-note {{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 {{use of identifier 'f' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} 17 g(); // expected-warning {{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>; 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; }; 307 template <typename T> struct B { struct NameFromBase { T m; }; }; 308 template <typename T> struct C : A<T>, B<T> { 309 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}} 310 }; 311 static_assert(sizeof(C<int>) == 4, ""); 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 {{unknown type name 'NameFromBase'}} 351 //expected-error@-1 {{expected member name or ';' after declaration specifiers}} 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 // FIXME: MSVC accepts this. 390 template <typename T> 391 struct C : B<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}} 392 } 393 394 namespace lookup_in_function_contexts { 395 template <typename T> struct A { typedef T NameFromBase; }; 396 template <typename T> 397 struct B : A<T> { 398 // expected-warning@+1 {{lookup into dependent bases}} 399 static auto lateSpecifiedFunc() -> decltype(NameFromBase()) { 400 return {}; 401 } 402 403 static void memberFunc() { 404 NameFromBase x; // expected-warning {{lookup into dependent bases}} 405 } 406 407 static void funcLocalClass() { 408 struct X { 409 NameFromBase x; // expected-warning {{lookup into dependent bases}} 410 } y; 411 } 412 413 void localClassMethod() { 414 struct X { 415 void bar() { 416 NameFromBase m; // expected-warning {{lookup into dependent bases}} 417 } 418 } x; 419 x.bar(); 420 } 421 422 static void funcLambda() { 423 auto l = []() { 424 NameFromBase x; // expected-warning {{lookup into dependent bases}} 425 }; 426 l(); 427 } 428 429 static constexpr int constexprFunc() { 430 NameFromBase x = {}; // expected-warning {{lookup into dependent bases}} 431 return sizeof(x); 432 } 433 434 static auto autoFunc() { 435 NameFromBase x; // expected-warning {{lookup into dependent bases}} 436 return x; 437 } 438 }; 439 440 // Force us to parse the methods. 441 template struct B<int>; 442 } 443 444 namespace function_template_deduction { 445 // Overloaded function templates. 446 template <int N> int f() { return N; } 447 template <typename T> int f() { return sizeof(T); } 448 449 // Dependent base class with type. 450 template <typename T> 451 struct A { typedef T NameFromBase; }; 452 template <typename T> 453 struct B : A<T> { 454 // expected-warning@+1 {{found via unqualified lookup into dependent bases}} 455 int x = f<NameFromBase>(); 456 }; 457 458 // Dependent base class with enum. 459 template <typename T> struct C { enum { NameFromBase = 4 }; }; 460 template <typename T> struct D : C<T> { 461 // expected-warning@+1 {{use of undeclared identifier 'NameFromBase'; unqualified lookup into dependent bases}} 462 int x = f<NameFromBase>(); 463 }; 464 } 465 466 namespace function_template_undef_impl { 467 template<class T> 468 void f() { 469 Undef::staticMethod(); // expected-error {{use of undeclared identifier 'Undef'}} 470 UndefVar.method(); // expected-error {{use of undeclared identifier 'UndefVar'}} 471 } 472 } 473 474 namespace PR20716 { 475 template <template <typename T> class A> 476 struct B : A<int> 477 { 478 XXX x; // expected-error {{unknown type name}} 479 }; 480 481 template <typename T> 482 struct C {}; 483 484 template <typename T> 485 using D = C<T>; 486 487 template <typename T> 488 struct E : D<T> 489 { 490 XXX x; // expected-error {{unknown type name}} 491 }; 492 } 493