Home | History | Annotate | Download | only in SemaTemplate
      1 // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -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 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 
     11 template <class T>
     12 class B : public A<T> {
     13 public:
     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 
     21 template class B<int>; // expected-note {{requested here}}
     22 template class B<char>; // expected-note {{requested here}}
     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; }; // expected-note {{member found by ambiguous name lookup}}
    307 template <typename T> struct B { struct NameFromBase { T m; }; }; // expected-note {{member found by ambiguous name lookup}}
    308 template <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 };
    311 static_assert(sizeof(C<int>) != 0, ""); // expected-note {{in instantiation of template class 'two_types_in_base::C<int>' requested here}}
    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 template <typename T>
    390 struct 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 
    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 identifier '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 identifier '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 identifier '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 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:}}
    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 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 };
    443 template<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 };
    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