642 lines · cpp
1// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++1y -fms-compatibility -fno-spell-checking -fsyntax-only -verify %s2// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++20 -fms-compatibility -fno-spell-checking -fsyntax-only -verify %s3 4 5template <class T>6class A {7public: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 12template <class T>13class B : public A<T> {14public: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 22template class B<int>; // expected-note {{requested here}}23template class B<char>; // expected-note {{requested here}}24 25void test()26{27 B<int> b;28 b.z(3);29}30 31struct 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};37template void A2::f(int);38 39template<class T0>40struct A3 {41 template<class T1> void f(T1) {42 XX; //expected-error {{use of undeclared identifier 'XX'}}43 }44};45template void A3<int>::f(int);46 47template<class T0>48struct A4 {49 void f(char) {50 XX; //expected-error {{use of undeclared identifier 'XX'}}51 }52};53template class A4<int>;54 55 56namespace lookup_dependent_bases_id_expr {57 58template<class T> class A {59public:60 int var;61};62 63 64template<class T>65class B : public A<T> {66public: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 72template class B<int>;73 74template<typename T> struct C;75 76// Test lookup with incomplete lookup context77template<typename T>78auto C<T>::f() -> decltype(x) { } // expected-error {{use of undeclared identifier 'x'}}79 // expected-error@-1 {{out-of-line definition of 'f' from class 'lookup_dependent_bases_id_expr::C<T>' without definition}}80 81}82 83 84 85namespace lookup_dependent_base_class_static_function {86 87template <class T>88class A {89public:90 static void static_func();// expected-note {{must qualify identifier to find this declaration in dependent base class}}91 void func();// expected-note {{must qualify identifier to find this declaration in dependent base class}}92};93 94 95template <class T>96class B : public A<T> {97public:98 static void z2(){99 static_func(); // expected-warning {{use of member 'static_func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}100 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}}101 }102};103template class B<int>; // expected-note {{requested here}}104 105}106 107 108 109namespace lookup_dependent_base_class_default_argument {110 111template<class T>112class A {113public:114 static int f1(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}115 int f2(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}116};117 118template<class T>119class B : public A<T> {120public:121 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}}122 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}}123};124 125void foo()126{127 B<int> b;128 b.g1(); // expected-note {{required here}}129 b.g2(); // expected-note {{required here}}130}131 132}133 134 135namespace lookup_dependent_base_class_friend {136 137template <class T>138class B {139public:140 static void g(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}141};142 143template <class T>144class A : public B<T> {145public:146 friend void foo(A<T> p){147 g(); // expected-warning {{use of member 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}148 }149};150 151int main2()152{153 A<int> a;154 foo(a); // expected-note {{requested here}}155}156 157}158 159 160namespace lookup_dependent_base_no_typo_correction {161 162class C {163public:164 int m_hWnd;165};166 167template <class T>168class A : public T {169public:170 void f(int hWnd) {171 m_hWnd = 1; // expected-warning {{use of undeclared identifier 'm_hWnd'; unqualified lookup into dependent bases of class template 'A' is a Microsoft extension}}172 }173};174 175template class A<C>;176 177}178 179namespace PR12701 {180 181class A {};182class B {};183 184template <class T>185class Base {186 public:187 bool base_fun(void* p) { return false; } // expected-note {{must qualify identifier to find this declaration in dependent base class}}188 operator T*() const { return 0; }189};190 191template <class T>192class Container : public Base<T> {193 public:194 template <typename S>195 bool operator=(const Container<S>& rhs) {196 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}}197 }198};199 200void f() {201 Container<A> text_provider;202 Container<B> text_provider2;203 text_provider2 = text_provider; // expected-note {{in instantiation of function template specialization}}204}205 206} // namespace PR12701207 208namespace PR16014 {209 210struct A {211 int a;212 static int sa;213};214template <typename T> struct B : T {215 int foo() { return a; } // expected-warning {{lookup into dependent bases}}216 int *bar() { return &a; } // expected-warning {{lookup into dependent bases}}217 int baz() { return T::a; }218 int T::*qux() { return &T::a; }219 static int T::*stuff() { return &T::a; }220 static int stuff1() { return T::sa; }221 static int *stuff2() { return &T::sa; }222 static int stuff3() { return sa; } // expected-warning {{lookup into dependent bases}}223 static int *stuff4() { return &sa; } // expected-warning {{lookup into dependent bases}}224};225 226template <typename T> struct C : T {227 int foo() { return b; } // expected-error {{no member named 'b' in 'PR16014::C<A>'}} expected-warning {{lookup into dependent bases}}228 int *bar() { return &b; } // expected-error {{no member named 'b' in 'PR16014::C<A>'}} expected-warning {{lookup into dependent bases}}229 int baz() { return T::b; } // expected-error {{no member named 'b' in 'PR16014::A'}}230 int T::*qux() { return &T::b; } // expected-error {{no member named 'b' in 'PR16014::A'}}231 int T::*fuz() { return &U::a; } // expected-error {{no member named 'U' in 'PR16014::C<A>'}} \232 // expected-warning {{unqualified lookup into dependent bases of class template 'C'}}233};234 235template struct B<A>;236template struct C<A>; // expected-note-re 1+ {{in instantiation of member function 'PR16014::C<PR16014::A>::{{.*}}' requested here}}237 238template <typename T> struct D : T {239 struct Inner {240 int foo() {241 // FIXME: MSVC can find this in D's base T! Even worse, if ::sa exists,242 // clang will use it instead.243 return sa; // expected-error {{use of undeclared identifier 'sa'}}244 }245 };246};247template struct D<A>;248 249}250 251namespace PR19233 {252template <class T>253struct A : T {254 void foo() {255 ::undef(); // expected-error {{no member named 'undef' in the global namespace}}256 }257 void bar() {258 ::UndefClass::undef(); // expected-error {{no member named 'UndefClass' in the global namespace}}259 }260 void baz() {261 B::qux(); // expected-error {{no member named 'B' in 'PR19233::A<D>'}} \262 // expected-warning {{unqualified lookup into dependent bases of class template 'A'}}263 }264};265 266struct B { void qux(); };267struct C : B { };268template struct A<C>; // No error! B is a base of A<C>, and qux is available.269 270struct D { };271template struct A<D>; // expected-note {{in instantiation of member function 'PR19233::A<PR19233::D>::baz' requested here}}272 273}274 275namespace nonmethod_missing_this {276template <typename T> struct Base { int y = 42; };277template <typename T> struct Derived : Base<T> {278 int x = y; // expected-warning {{lookup into dependent bases}}279 auto foo(int j) -> decltype(y * j) { // expected-warning {{lookup into dependent bases}}280 return y * j; // expected-warning {{lookup into dependent bases}}281 }282 int bar() {283 return [&] { return y; }(); // expected-warning {{lookup into dependent bases}}284 }285};286template struct Derived<int>;287}288 289namespace typedef_in_base {290template <typename T> struct A { typedef T NameFromBase; };291template <typename T> struct B : A<T> {292 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}293};294static_assert(sizeof(B<int>) == 4, "");295}296 297namespace struct_in_base {298template <typename T> struct A { struct NameFromBase {}; };299template <typename T> struct B : A<T> {300 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}301};302static_assert(sizeof(B<int>) == 1, "");303}304 305namespace enum_in_base {306template <typename T> struct A { enum NameFromBase { X }; };307template <typename T> struct B : A<T> {308 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}309};310static_assert(sizeof(B<int>) == sizeof(A<int>::NameFromBase), "");311}312 313namespace two_types_in_base {314template <typename T> struct A { typedef T NameFromBase; }; // expected-note {{member type 'int' found by ambiguous name lookup}}315template <typename T> struct B { struct NameFromBase { T m; }; }; // expected-note {{member type 'two_types_in_base::B<int>::NameFromBase' found by ambiguous name lookup}}316template <typename T> struct C : A<T>, B<T> {317 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}}318};319static_assert(sizeof(C<int>) != 0, ""); // expected-note {{in instantiation of template class 'two_types_in_base::C<int>' requested here}}320}321 322namespace type_and_decl_in_base {323template <typename T> struct A { typedef T NameFromBase; };324template <typename T> struct B { static const T NameFromBase = 42; };325template <typename T> struct C : A<T>, B<T> {326 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}327};328}329 330namespace classify_type_from_base {331template <typename T> struct A { struct NameFromBase {}; };332template <typename T> struct B : A<T> {333 A<NameFromBase> m; // expected-warning {{found via unqualified lookup into dependent bases}}334};335}336 337namespace classify_nontype_from_base {338// MSVC does not do lookup of non-type declarations from dependent template base339// classes. The extra lookup only applies to types.340template <typename T> struct A { void NameFromBase() {} };341template <void (*F)()> struct B { };342template <typename T> struct C : A<T> {343 B<C::NameFromBase> a; // correct344 B<NameFromBase> b; // expected-error {{use of undeclared identifier 'NameFromBase'}}345};346}347 348namespace template_in_base {349template <typename T> struct A {350 template <typename U> struct NameFromBase { U x; };351};352template <typename T> struct B : A<T> {353 // Correct form.354 typename B::template NameFromBase<T> m;355};356template <typename T> struct C : A<T> {357 // Incorrect form.358 NameFromBase<T> m; // expected-error {{no template named 'NameFromBase'}}359};360}361 362namespace type_in_inner_class_in_base {363template <typename T>364struct A {365 struct B { typedef T NameFromBase; };366};367template <typename T>368struct C : A<T>::B { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}369}370 371namespace type_in_inner_template_class_in_base {372template <typename T>373struct A {374 template <typename U> struct B { typedef U InnerType; };375};376template <typename T>377struct C : A<T>::template B<T> {378 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}379};380}381 382namespace have_nondependent_base {383template <typename T>384struct A {385 // Nothing, lookup should fail.386};387template <typename T>388struct B : A<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}389struct C : A<int> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}390}391 392namespace type_in_base_of_dependent_base {393struct A { typedef int NameFromBase; };394template <typename T>395struct B : A {};396template <typename T>397struct 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}}398}399 400namespace type_in_second_dependent_base {401template <typename T>402struct A {};403template<typename T>404struct B { typedef T NameFromBase; };405template <typename T>406struct 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}}407}408 409namespace type_in_second_non_dependent_base {410struct A {};411struct B { typedef int NameFromBase; };412template<typename T>413struct C : A, B {};414template <typename T>415struct 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}}416}417 418namespace type_in_virtual_base_of_dependent_base {419template <typename T>420struct A { typedef T NameFromBase; };421template <typename T>422struct B : virtual A<T> {};423template <typename T>424struct 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}}425C<int> c;426}427 428namespace type_in_base_of_multiple_dependent_bases {429template <typename T>430struct A { typedef T NameFromBase; };431template <typename T>432struct B : public A<T> {};433template <typename T>434struct 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:}}435C<int> c; // expected-note {{in instantiation of template class 'type_in_base_of_multiple_dependent_bases::C<int>' requested here}}436}437 438namespace type_in_dependent_base_of_non_dependent_type {439template<typename T> struct A { typedef int NameFromBase; };440template<typename T> struct B : A<T> {441 struct C;442 template<typename TT>443 struct D : C {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 struct E : C {447 NameFromBase m; // expected-warning {{use of member 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}448 };449};450template<typename T> struct B<T>::C : B {451 NameFromBase m; // expected-warning {{use of member 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}452};453template<typename T> struct F : B<T>::C {454 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}455};456}457 458namespace lookup_in_function_contexts {459template <typename T> struct A { typedef T NameFromBase; };460template <typename T>461struct B : A<T> {462 // expected-warning@+1 {{lookup into dependent bases}}463 static auto lateSpecifiedFunc() -> decltype(NameFromBase()) {464 return {};465 }466 467 static void memberFunc() {468 NameFromBase x; // expected-warning {{lookup into dependent bases}}469 }470 471 static void funcLocalClass() {472 struct X {473 NameFromBase x; // expected-warning {{lookup into dependent bases}}474 } y;475 }476 477 void localClassMethod() {478 struct X {479 void bar() {480 NameFromBase m; // expected-warning {{lookup into dependent bases}}481 }482 } x;483 x.bar();484 }485 486 static void funcLambda() {487 auto l = []() {488 NameFromBase x; // expected-warning {{lookup into dependent bases}}489 };490 l();491 }492 493 static constexpr int constexprFunc() {494 NameFromBase x = {}; // expected-warning {{lookup into dependent bases}}495 return sizeof(x);496 }497 498 static auto autoFunc() {499 NameFromBase x; // expected-warning {{lookup into dependent bases}}500 return x;501 }502};503 504// Force us to parse the methods.505template struct B<int>;506}507 508namespace function_template_deduction {509// Overloaded function templates.510template <int N> int f() { return N; }511template <typename T> int f() { return sizeof(T); }512 513// Dependent base class with type.514template <typename T>515struct A { typedef T NameFromBase; };516template <typename T>517struct B : A<T> {518 // expected-warning@+1 {{found via unqualified lookup into dependent bases}}519 int x = f<NameFromBase>();520};521 522// Dependent base class with enum.523template <typename T> struct C { enum { NameFromBase = 4 }; };524template <typename T> struct D : C<T> {525 // expected-warning@+1 {{use of undeclared identifier 'NameFromBase'; unqualified lookup into dependent bases}}526 int x = f<NameFromBase>();527};528}529 530namespace function_template_undef_impl {531template<class T>532void f() {533 Undef::staticMethod(); // expected-error {{use of undeclared identifier 'Undef'}}534 UndefVar.method(); // expected-error {{use of undeclared identifier 'UndefVar'}}535}536}537 538namespace PR20716 {539template <template <typename T> class A>540struct B : A<int>541{542 XXX x; // expected-error {{unknown type name}}543};544 545template <typename T>546struct C {};547 548template <typename T>549using D = C<T>;550 551template <typename T>552struct E : D<T>553{554 XXX x; // expected-error {{unknown type name}}555};556}557 558namespace PR23810 {559void f(int);560struct Base {561 void f(); // expected-note{{must qualify identifier to find this declaration in dependent base class}}562};563template <typename T> struct Template : T {564 void member() {565 f(); // expected-warning {{found via unqualified lookup into dependent bases}}566 }567};568void test() {569 Template<Base> x;570 x.member(); // expected-note{{requested here}}571};572}573 574namespace PR23823 {575// Don't delay lookup in SFINAE context.576template <typename T> decltype(g(T())) check(); // expected-note{{candidate template ignored: substitution failure [with T = int]: use of undeclared identifier 'g'}}577decltype(check<int>()) x; // expected-error{{no matching function for call to 'check'}}578 579void h();580template <typename T> decltype(h(T())) check2(); // expected-note{{candidate template ignored: substitution failure [with T = int]: no matching function for call to 'h'}}581decltype(check2<int>()) y; // expected-error{{no matching function for call to 'check2'}}582}583 584// We also allow unqualified lookup into bases in contexts where the we know the585// undeclared identifier *must* be a type, such as a new expression or catch586// parameter type.587template <typename T>588struct UseUnqualifiedTypeNames : T {589 void foo() {590 void *P = new TheType; // expected-warning {{unqualified lookup}} expected-error {{no type}}591 size_t x = __builtin_offsetof(TheType, f2); // expected-warning {{unqualified lookup}} expected-error {{no type}}592 try {593 } catch (TheType) { // expected-warning {{unqualified lookup}} expected-error {{no type}}594 }595 enum E : IntegerType { E0 = 42 }; // expected-warning {{unqualified lookup}} expected-error {{no type}}596 _Atomic(TheType) a; // expected-warning {{unqualified lookup}} expected-error {{no type}}597 }598 void out_of_line();599};600template <typename T>601void UseUnqualifiedTypeNames<T>::out_of_line() {602 void *p = new TheType; // expected-warning {{unqualified lookup}} expected-error {{no type}}603}604struct Base {605 typedef int IntegerType;606 struct TheType {607 int f1, f2;608 };609};610template struct UseUnqualifiedTypeNames<Base>;611struct BadBase { };612template struct UseUnqualifiedTypeNames<BadBase>; // expected-note-re 2 {{in instantiation {{.*}} requested here}}613 614namespace partial_template_lookup {615 616class Bar;617class Spare;618 619template <class T, class X = Bar>620class FooTemplated;621 622class FooBase {623public:624 typedef int BaseTypedef;625};626 627// Partial template spec (unused)628template <class T>629class FooTemplated<T, Spare> {};630 631// Partial template spec (used)632template <class T>633class FooTemplated<T, Bar> : public FooBase {};634 635// Full template spec636template <class T, class X>637class FooTemplated : public FooTemplated<T, Bar> {638public:639 BaseTypedef Member; // expected-warning {{unqualified lookup}}640};641}642