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 }; 225 226 template struct B<A>; 227 template struct C<A>; // expected-note-re 1+ {{in instantiation of member function 'PR16014::C<PR16014::A>::{{.*}}' requested here}} 228 229 template <typename T> struct D : T { 230 struct Inner { 231 int foo() { 232 // FIXME: MSVC can find this in D's base T! Even worse, if ::sa exists, 233 // clang will use it instead. 234 return sa; // expected-error {{use of undeclared identifier 'sa'}} 235 } 236 }; 237 }; 238 template struct D<A>; 239 240 } 241 242 namespace PR19233 { 243 template <class T> 244 struct A : T { 245 void foo() { 246 ::undef(); // expected-error {{no member named 'undef' in the global namespace}} 247 } 248 void bar() { 249 ::UndefClass::undef(); // expected-error {{no member named 'UndefClass' in the global namespace}} 250 } 251 void baz() { 252 B::qux(); // expected-error {{use of undeclared identifier 'B'}} 253 } 254 }; 255 256 struct B { void qux(); }; 257 struct C : B { }; 258 template struct A<C>; // No error! B is a base of A<C>, and qux is available. 259 260 struct D { }; 261 template struct A<D>; // expected-note {{in instantiation of member function 'PR19233::A<PR19233::D>::baz' requested here}} 262 263 } 264 265 namespace nonmethod_missing_this { 266 template <typename T> struct Base { int y = 42; }; 267 template <typename T> struct Derived : Base<T> { 268 int x = y; // expected-warning {{lookup into dependent bases}} 269 auto foo(int j) -> decltype(y * j) { // expected-warning {{lookup into dependent bases}} 270 return y * j; // expected-warning {{lookup into dependent bases}} 271 } 272 int bar() { 273 return [&] { return y; }(); // expected-warning {{lookup into dependent bases}} 274 } 275 }; 276 template struct Derived<int>; 277 } 278 279 namespace typedef_in_base { 280 template <typename T> struct A { typedef T NameFromBase; }; 281 template <typename T> struct B : A<T> { 282 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}} 283 }; 284 static_assert(sizeof(B<int>) == 4, ""); 285 } 286 287 namespace struct_in_base { 288 template <typename T> struct A { struct NameFromBase {}; }; 289 template <typename T> struct B : A<T> { 290 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}} 291 }; 292 static_assert(sizeof(B<int>) == 1, ""); 293 } 294 295 namespace enum_in_base { 296 template <typename T> struct A { enum NameFromBase { X }; }; 297 template <typename T> struct B : A<T> { 298 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}} 299 }; 300 static_assert(sizeof(B<int>) == sizeof(A<int>::NameFromBase), ""); 301 } 302 303 namespace two_types_in_base { 304 template <typename T> struct A { typedef T NameFromBase; }; 305 template <typename T> struct B { struct NameFromBase { T m; }; }; 306 template <typename T> struct C : A<T>, B<T> { 307 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}} 308 }; 309 static_assert(sizeof(C<int>) == 4, ""); 310 } 311 312 namespace type_and_decl_in_base { 313 template <typename T> struct A { typedef T NameFromBase; }; 314 template <typename T> struct B { static const T NameFromBase = 42; }; 315 template <typename T> struct C : A<T>, B<T> { 316 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}} 317 }; 318 } 319 320 namespace classify_type_from_base { 321 template <typename T> struct A { struct NameFromBase {}; }; 322 template <typename T> struct B : A<T> { 323 A<NameFromBase> m; // expected-warning {{found via unqualified lookup into dependent bases}} 324 }; 325 } 326 327 namespace classify_nontype_from_base { 328 // MSVC does not do lookup of non-type declarations from dependent template base 329 // classes. The extra lookup only applies to types. 330 template <typename T> struct A { void NameFromBase() {} }; 331 template <void (*F)()> struct B { }; 332 template <typename T> struct C : A<T> { 333 B<C::NameFromBase> a; // correct 334 B<NameFromBase> b; // expected-error {{use of undeclared identifier 'NameFromBase'}} 335 }; 336 } 337 338 namespace template_in_base { 339 template <typename T> struct A { 340 template <typename U> struct NameFromBase { U x; }; 341 }; 342 template <typename T> struct B : A<T> { 343 // Correct form. 344 typename B::template NameFromBase<T> m; 345 }; 346 template <typename T> struct C : A<T> { 347 // Incorrect form. 348 NameFromBase<T> m; // expected-error {{unknown type name 'NameFromBase'}} 349 //expected-error@-1 {{expected member name or ';' after declaration specifiers}} 350 }; 351 } 352 353 namespace type_in_inner_class_in_base { 354 template <typename T> 355 struct A { 356 struct B { typedef T NameFromBase; }; 357 }; 358 template <typename T> 359 struct C : A<T>::B { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}} 360 } 361 362 namespace type_in_inner_template_class_in_base { 363 template <typename T> 364 struct A { 365 template <typename U> struct B { typedef U InnerType; }; 366 }; 367 template <typename T> 368 struct C : A<T>::template B<T> { 369 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}} 370 }; 371 } 372 373 namespace have_nondependent_base { 374 template <typename T> 375 struct A { 376 // Nothing, lookup should fail. 377 }; 378 template <typename T> 379 struct B : A<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}} 380 struct C : A<int> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}} 381 } 382 383 namespace type_in_base_of_dependent_base { 384 struct A { typedef int NameFromBase; }; 385 template <typename T> 386 struct B : A {}; 387 // FIXME: MSVC accepts this. 388 template <typename T> 389 struct C : B<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}} 390 } 391 392 namespace lookup_in_function_contexts { 393 template <typename T> struct A { typedef T NameFromBase; }; 394 template <typename T> 395 struct B : A<T> { 396 // expected-warning@+1 {{lookup into dependent bases}} 397 static auto lateSpecifiedFunc() -> decltype(NameFromBase()) { 398 return {}; 399 } 400 401 static void memberFunc() { 402 NameFromBase x; // expected-warning {{lookup into dependent bases}} 403 } 404 405 static void funcLocalClass() { 406 struct X { 407 NameFromBase x; // expected-warning {{lookup into dependent bases}} 408 } y; 409 } 410 411 void localClassMethod() { 412 struct X { 413 void bar() { 414 NameFromBase m; // expected-warning {{lookup into dependent bases}} 415 } 416 } x; 417 x.bar(); 418 } 419 420 static void funcLambda() { 421 auto l = []() { 422 NameFromBase x; // expected-warning {{lookup into dependent bases}} 423 }; 424 l(); 425 } 426 427 static constexpr int constexprFunc() { 428 NameFromBase x = {}; // expected-warning {{lookup into dependent bases}} 429 return sizeof(x); 430 } 431 432 static auto autoFunc() { 433 NameFromBase x; // expected-warning {{lookup into dependent bases}} 434 return x; 435 } 436 }; 437 438 // Force us to parse the methods. 439 template struct B<int>; 440 } 441 442 namespace function_template_deduction { 443 // Overloaded function templates. 444 template <int N> int f() { return N; } 445 template <typename T> int f() { return sizeof(T); } 446 447 // Dependent base class with type. 448 template <typename T> 449 struct A { typedef T NameFromBase; }; 450 template <typename T> 451 struct B : A<T> { 452 // expected-warning@+1 {{found via unqualified lookup into dependent bases}} 453 int x = f<NameFromBase>(); 454 }; 455 456 // Dependent base class with enum. 457 template <typename T> struct C { enum { NameFromBase = 4 }; }; 458 template <typename T> struct D : C<T> { 459 // expected-warning@+1 {{use of undeclared identifier 'NameFromBase'; unqualified lookup into dependent bases}} 460 int x = f<NameFromBase>(); 461 }; 462 } 463