1// RUN: %clang_cc1 -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 {{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 11template <class T> 12class B : public A<T> { 13public: 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 21template class B<int>; // expected-note {{requested here}} 22template class B<char>; 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}; 225 226template struct B<A>; 227template struct C<A>; // expected-note-re 1+ {{in instantiation of member function 'PR16014::C<PR16014::A>::{{.*}}' requested here}} 228 229template <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}; 238template struct D<A>; 239 240} 241 242namespace PR19233 { 243template <class T> 244struct 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 256struct B { void qux(); }; 257struct C : B { }; 258template struct A<C>; // No error! B is a base of A<C>, and qux is available. 259 260struct D { }; 261template struct A<D>; // expected-note {{in instantiation of member function 'PR19233::A<PR19233::D>::baz' requested here}} 262 263} 264 265namespace nonmethod_missing_this { 266template <typename T> struct Base { int y = 42; }; 267template <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}; 276template struct Derived<int>; 277} 278 279namespace typedef_in_base { 280template <typename T> struct A { typedef T NameFromBase; }; 281template <typename T> struct B : A<T> { 282 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}} 283}; 284static_assert(sizeof(B<int>) == 4, ""); 285} 286 287namespace struct_in_base { 288template <typename T> struct A { struct NameFromBase {}; }; 289template <typename T> struct B : A<T> { 290 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}} 291}; 292static_assert(sizeof(B<int>) == 1, ""); 293} 294 295namespace enum_in_base { 296template <typename T> struct A { enum NameFromBase { X }; }; 297template <typename T> struct B : A<T> { 298 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}} 299}; 300static_assert(sizeof(B<int>) == sizeof(A<int>::NameFromBase), ""); 301} 302 303namespace two_types_in_base { 304template <typename T> struct A { typedef T NameFromBase; }; 305template <typename T> struct B { struct NameFromBase { T m; }; }; 306template <typename T> struct C : A<T>, B<T> { 307 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}} 308}; 309static_assert(sizeof(C<int>) == 4, ""); 310} 311 312namespace type_and_decl_in_base { 313template <typename T> struct A { typedef T NameFromBase; }; 314template <typename T> struct B { static const T NameFromBase = 42; }; 315template <typename T> struct C : A<T>, B<T> { 316 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}} 317}; 318} 319 320namespace classify_type_from_base { 321template <typename T> struct A { struct NameFromBase {}; }; 322template <typename T> struct B : A<T> { 323 A<NameFromBase> m; // expected-warning {{found via unqualified lookup into dependent bases}} 324}; 325} 326 327namespace 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. 330template <typename T> struct A { void NameFromBase() {} }; 331template <void (*F)()> struct B { }; 332template <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 338namespace template_in_base { 339template <typename T> struct A { 340 template <typename U> struct NameFromBase { U x; }; 341}; 342template <typename T> struct B : A<T> { 343 // Correct form. 344 typename B::template NameFromBase<T> m; 345}; 346template <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 353namespace type_in_inner_class_in_base { 354template <typename T> 355struct A { 356 struct B { typedef T NameFromBase; }; 357}; 358template <typename T> 359struct C : A<T>::B { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}} 360} 361 362namespace type_in_inner_template_class_in_base { 363template <typename T> 364struct A { 365 template <typename U> struct B { typedef U InnerType; }; 366}; 367template <typename T> 368struct C : A<T>::template B<T> { 369 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}} 370}; 371} 372 373namespace have_nondependent_base { 374template <typename T> 375struct A { 376 // Nothing, lookup should fail. 377}; 378template <typename T> 379struct B : A<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}} 380struct C : A<int> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}} 381} 382 383namespace type_in_base_of_dependent_base { 384struct A { typedef int NameFromBase; }; 385template <typename T> 386struct B : A {}; 387// FIXME: MSVC accepts this. 388template <typename T> 389struct C : B<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}} 390} 391 392namespace lookup_in_function_contexts { 393template <typename T> struct A { typedef T NameFromBase; }; 394template <typename T> 395struct 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. 439template struct B<int>; 440} 441 442namespace function_template_deduction { 443// Overloaded function templates. 444template <int N> int f() { return N; } 445template <typename T> int f() { return sizeof(T); } 446 447// Dependent base class with type. 448template <typename T> 449struct A { typedef T NameFromBase; }; 450template <typename T> 451struct 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. 457template <typename T> struct C { enum { NameFromBase = 4 }; }; 458template <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