ms-lookup-template-base-classes.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. // RUN: %clang_cc1 -std=c++1y -fms-compatibility -fno-spell-checking -fsyntax-only -verify %s
  2. template <class T>
  3. class A {
  4. public:
  5. void f(T a) { }// expected-note {{must qualify identifier to find this declaration in dependent base class}}
  6. void g();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
  7. };
  8. template <class T>
  9. class B : public A<T> {
  10. public:
  11. void z(T a)
  12. {
  13. f(a); // expected-warning {{use of identifier 'f' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
  14. g(); // expected-warning {{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
  15. }
  16. };
  17. template class B<int>; // expected-note {{requested here}}
  18. template class B<char>;
  19. void test()
  20. {
  21. B<int> b;
  22. b.z(3);
  23. }
  24. struct A2 {
  25. template<class T> void f(T) {
  26. XX; //expected-error {{use of undeclared identifier 'XX'}}
  27. A2::XX; //expected-error {{no member named 'XX' in 'A2'}}
  28. }
  29. };
  30. template void A2::f(int);
  31. template<class T0>
  32. struct A3 {
  33. template<class T1> void f(T1) {
  34. XX; //expected-error {{use of undeclared identifier 'XX'}}
  35. }
  36. };
  37. template void A3<int>::f(int);
  38. template<class T0>
  39. struct A4 {
  40. void f(char) {
  41. XX; //expected-error {{use of undeclared identifier 'XX'}}
  42. }
  43. };
  44. template class A4<int>;
  45. namespace lookup_dependent_bases_id_expr {
  46. template<class T> class A {
  47. public:
  48. int var;
  49. };
  50. template<class T>
  51. class B : public A<T> {
  52. public:
  53. void f() {
  54. var = 3; // expected-warning {{use of undeclared identifier 'var'; unqualified lookup into dependent bases of class template 'B' is a Microsoft extension}}
  55. }
  56. };
  57. template class B<int>;
  58. }
  59. namespace lookup_dependent_base_class_static_function {
  60. template <class T>
  61. class A {
  62. public:
  63. static void static_func();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
  64. void func();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
  65. };
  66. template <class T>
  67. class B : public A<T> {
  68. public:
  69. static void z2(){
  70. static_func(); // expected-warning {{use of identifier 'static_func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
  71. 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}}
  72. }
  73. };
  74. template class B<int>; // expected-note {{requested here}}
  75. }
  76. namespace lookup_dependent_base_class_default_argument {
  77. template<class T>
  78. class A {
  79. public:
  80. static int f1(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
  81. int f2(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
  82. };
  83. template<class T>
  84. class B : public A<T> {
  85. public:
  86. 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}}
  87. 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}}
  88. };
  89. void foo()
  90. {
  91. B<int> b;
  92. b.g1(); // expected-note {{required here}}
  93. b.g2(); // expected-note {{required here}}
  94. }
  95. }
  96. namespace lookup_dependent_base_class_friend {
  97. template <class T>
  98. class B {
  99. public:
  100. static void g(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
  101. };
  102. template <class T>
  103. class A : public B<T> {
  104. public:
  105. friend void foo(A<T> p){
  106. g(); // expected-warning {{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
  107. }
  108. };
  109. int main2()
  110. {
  111. A<int> a;
  112. foo(a); // expected-note {{requested here}}
  113. }
  114. }
  115. namespace lookup_dependent_base_no_typo_correction {
  116. class C {
  117. public:
  118. int m_hWnd;
  119. };
  120. template <class T>
  121. class A : public T {
  122. public:
  123. void f(int hWnd) {
  124. m_hWnd = 1; // expected-warning {{use of undeclared identifier 'm_hWnd'; unqualified lookup into dependent bases of class template 'A' is a Microsoft extension}}
  125. }
  126. };
  127. template class A<C>;
  128. }
  129. namespace PR12701 {
  130. class A {};
  131. class B {};
  132. template <class T>
  133. class Base {
  134. public:
  135. bool base_fun(void* p) { return false; } // expected-note {{must qualify identifier to find this declaration in dependent base class}}
  136. operator T*() const { return 0; }
  137. };
  138. template <class T>
  139. class Container : public Base<T> {
  140. public:
  141. template <typename S>
  142. bool operator=(const Container<S>& rhs) {
  143. 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}}
  144. }
  145. };
  146. void f() {
  147. Container<A> text_provider;
  148. Container<B> text_provider2;
  149. text_provider2 = text_provider; // expected-note {{in instantiation of function template specialization}}
  150. }
  151. } // namespace PR12701
  152. namespace PR16014 {
  153. struct A {
  154. int a;
  155. static int sa;
  156. };
  157. template <typename T> struct B : T {
  158. int foo() { return a; } // expected-warning {{lookup into dependent bases}}
  159. int *bar() { return &a; } // expected-warning {{lookup into dependent bases}}
  160. int baz() { return T::a; }
  161. int T::*qux() { return &T::a; }
  162. static int T::*stuff() { return &T::a; }
  163. static int stuff1() { return T::sa; }
  164. static int *stuff2() { return &T::sa; }
  165. static int stuff3() { return sa; } // expected-warning {{lookup into dependent bases}}
  166. static int *stuff4() { return &sa; } // expected-warning {{lookup into dependent bases}}
  167. };
  168. template <typename T> struct C : T {
  169. int foo() { return b; } // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
  170. int *bar() { return &b; } // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
  171. int baz() { return T::b; } // expected-error {{no member named 'b' in 'PR16014::A'}}
  172. int T::*qux() { return &T::b; } // expected-error {{no member named 'b' in 'PR16014::A'}}
  173. int T::*fuz() { return &U::a; } // expected-error {{use of undeclared identifier 'U'}} \
  174. // expected-warning {{unqualified lookup into dependent bases of class template 'C'}}
  175. };
  176. template struct B<A>;
  177. template struct C<A>; // expected-note-re 1+ {{in instantiation of member function 'PR16014::C<PR16014::A>::{{.*}}' requested here}}
  178. template <typename T> struct D : T {
  179. struct Inner {
  180. int foo() {
  181. // FIXME: MSVC can find this in D's base T! Even worse, if ::sa exists,
  182. // clang will use it instead.
  183. return sa; // expected-error {{use of undeclared identifier 'sa'}}
  184. }
  185. };
  186. };
  187. template struct D<A>;
  188. }
  189. namespace PR19233 {
  190. template <class T>
  191. struct A : T {
  192. void foo() {
  193. ::undef(); // expected-error {{no member named 'undef' in the global namespace}}
  194. }
  195. void bar() {
  196. ::UndefClass::undef(); // expected-error {{no member named 'UndefClass' in the global namespace}}
  197. }
  198. void baz() {
  199. B::qux(); // expected-error {{use of undeclared identifier 'B'}} \
  200. // expected-warning {{unqualified lookup into dependent bases of class template 'A'}}
  201. }
  202. };
  203. struct B { void qux(); };
  204. struct C : B { };
  205. template struct A<C>; // No error! B is a base of A<C>, and qux is available.
  206. struct D { };
  207. template struct A<D>; // expected-note {{in instantiation of member function 'PR19233::A<PR19233::D>::baz' requested here}}
  208. }
  209. namespace nonmethod_missing_this {
  210. template <typename T> struct Base { int y = 42; };
  211. template <typename T> struct Derived : Base<T> {
  212. int x = y; // expected-warning {{lookup into dependent bases}}
  213. auto foo(int j) -> decltype(y * j) { // expected-warning {{lookup into dependent bases}}
  214. return y * j; // expected-warning {{lookup into dependent bases}}
  215. }
  216. int bar() {
  217. return [&] { return y; }(); // expected-warning {{lookup into dependent bases}}
  218. }
  219. };
  220. template struct Derived<int>;
  221. }
  222. namespace typedef_in_base {
  223. template <typename T> struct A { typedef T NameFromBase; };
  224. template <typename T> struct B : A<T> {
  225. NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
  226. };
  227. static_assert(sizeof(B<int>) == 4, "");
  228. }
  229. namespace struct_in_base {
  230. template <typename T> struct A { struct NameFromBase {}; };
  231. template <typename T> struct B : A<T> {
  232. NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
  233. };
  234. static_assert(sizeof(B<int>) == 1, "");
  235. }
  236. namespace enum_in_base {
  237. template <typename T> struct A { enum NameFromBase { X }; };
  238. template <typename T> struct B : A<T> {
  239. NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
  240. };
  241. static_assert(sizeof(B<int>) == sizeof(A<int>::NameFromBase), "");
  242. }
  243. namespace two_types_in_base {
  244. template <typename T> struct A { typedef T NameFromBase; }; // expected-note {{member found by ambiguous name lookup}}
  245. template <typename T> struct B { struct NameFromBase { T m; }; }; // expected-note {{member found by ambiguous name lookup}}
  246. template <typename T> struct C : A<T>, B<T> {
  247. 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}}
  248. };
  249. static_assert(sizeof(C<int>) == 4, ""); // expected-note {{in instantiation of template class 'two_types_in_base::C<int>' requested here}}
  250. }
  251. namespace type_and_decl_in_base {
  252. template <typename T> struct A { typedef T NameFromBase; };
  253. template <typename T> struct B { static const T NameFromBase = 42; };
  254. template <typename T> struct C : A<T>, B<T> {
  255. NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
  256. };
  257. }
  258. namespace classify_type_from_base {
  259. template <typename T> struct A { struct NameFromBase {}; };
  260. template <typename T> struct B : A<T> {
  261. A<NameFromBase> m; // expected-warning {{found via unqualified lookup into dependent bases}}
  262. };
  263. }
  264. namespace classify_nontype_from_base {
  265. // MSVC does not do lookup of non-type declarations from dependent template base
  266. // classes. The extra lookup only applies to types.
  267. template <typename T> struct A { void NameFromBase() {} };
  268. template <void (*F)()> struct B { };
  269. template <typename T> struct C : A<T> {
  270. B<C::NameFromBase> a; // correct
  271. B<NameFromBase> b; // expected-error {{use of undeclared identifier 'NameFromBase'}}
  272. };
  273. }
  274. namespace template_in_base {
  275. template <typename T> struct A {
  276. template <typename U> struct NameFromBase { U x; };
  277. };
  278. template <typename T> struct B : A<T> {
  279. // Correct form.
  280. typename B::template NameFromBase<T> m;
  281. };
  282. template <typename T> struct C : A<T> {
  283. // Incorrect form.
  284. NameFromBase<T> m; // expected-error {{unknown type name 'NameFromBase'}}
  285. //expected-error@-1 {{expected member name or ';' after declaration specifiers}}
  286. };
  287. }
  288. namespace type_in_inner_class_in_base {
  289. template <typename T>
  290. struct A {
  291. struct B { typedef T NameFromBase; };
  292. };
  293. template <typename T>
  294. struct C : A<T>::B { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
  295. }
  296. namespace type_in_inner_template_class_in_base {
  297. template <typename T>
  298. struct A {
  299. template <typename U> struct B { typedef U InnerType; };
  300. };
  301. template <typename T>
  302. struct C : A<T>::template B<T> {
  303. NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
  304. };
  305. }
  306. namespace have_nondependent_base {
  307. template <typename T>
  308. struct A {
  309. // Nothing, lookup should fail.
  310. };
  311. template <typename T>
  312. struct B : A<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
  313. struct C : A<int> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
  314. }
  315. namespace type_in_base_of_dependent_base {
  316. struct A { typedef int NameFromBase; };
  317. template <typename T>
  318. struct B : A {};
  319. template <typename T>
  320. 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}}
  321. }
  322. namespace type_in_second_dependent_base {
  323. template <typename T>
  324. struct A {};
  325. template<typename T>
  326. struct B { typedef T NameFromBase; };
  327. template <typename T>
  328. 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}}
  329. }
  330. namespace type_in_second_non_dependent_base {
  331. struct A {};
  332. struct B { typedef int NameFromBase; };
  333. template<typename T>
  334. struct C : A, B {};
  335. template <typename T>
  336. 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}}
  337. }
  338. namespace type_in_virtual_base_of_dependent_base {
  339. template <typename T>
  340. struct A { typedef T NameFromBase; };
  341. template <typename T>
  342. struct B : virtual A<T> {};
  343. template <typename T>
  344. 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}}
  345. C<int> c;
  346. }
  347. namespace type_in_base_of_multiple_dependent_bases {
  348. template <typename T>
  349. struct A { typedef T NameFromBase; };
  350. template <typename T>
  351. struct B : public A<T> {};
  352. template <typename T>
  353. 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:}}
  354. C<int> c; // expected-note {{in instantiation of template class 'type_in_base_of_multiple_dependent_bases::C<int>' requested here}}
  355. }
  356. namespace type_in_dependent_base_of_non_dependent_type {
  357. template<typename T> struct A { typedef int NameFromBase; };
  358. template<typename T> struct B : A<T> {
  359. struct C;
  360. template<typename TT>
  361. struct D : C {
  362. NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
  363. };
  364. struct E : C {
  365. NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
  366. };
  367. };
  368. template<typename T> struct B<T>::C : B {
  369. NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
  370. };
  371. template<typename T> struct F : B<T>::C {
  372. NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
  373. };
  374. }
  375. namespace lookup_in_function_contexts {
  376. template <typename T> struct A { typedef T NameFromBase; };
  377. template <typename T>
  378. struct B : A<T> {
  379. // expected-warning@+1 {{lookup into dependent bases}}
  380. static auto lateSpecifiedFunc() -> decltype(NameFromBase()) {
  381. return {};
  382. }
  383. static void memberFunc() {
  384. NameFromBase x; // expected-warning {{lookup into dependent bases}}
  385. }
  386. static void funcLocalClass() {
  387. struct X {
  388. NameFromBase x; // expected-warning {{lookup into dependent bases}}
  389. } y;
  390. }
  391. void localClassMethod() {
  392. struct X {
  393. void bar() {
  394. NameFromBase m; // expected-warning {{lookup into dependent bases}}
  395. }
  396. } x;
  397. x.bar();
  398. }
  399. static void funcLambda() {
  400. auto l = []() {
  401. NameFromBase x; // expected-warning {{lookup into dependent bases}}
  402. };
  403. l();
  404. }
  405. static constexpr int constexprFunc() {
  406. NameFromBase x = {}; // expected-warning {{lookup into dependent bases}}
  407. return sizeof(x);
  408. }
  409. static auto autoFunc() {
  410. NameFromBase x; // expected-warning {{lookup into dependent bases}}
  411. return x;
  412. }
  413. };
  414. // Force us to parse the methods.
  415. template struct B<int>;
  416. }
  417. namespace function_template_deduction {
  418. // Overloaded function templates.
  419. template <int N> int f() { return N; }
  420. template <typename T> int f() { return sizeof(T); }
  421. // Dependent base class with type.
  422. template <typename T>
  423. struct A { typedef T NameFromBase; };
  424. template <typename T>
  425. struct B : A<T> {
  426. // expected-warning@+1 {{found via unqualified lookup into dependent bases}}
  427. int x = f<NameFromBase>();
  428. };
  429. // Dependent base class with enum.
  430. template <typename T> struct C { enum { NameFromBase = 4 }; };
  431. template <typename T> struct D : C<T> {
  432. // expected-warning@+1 {{use of undeclared identifier 'NameFromBase'; unqualified lookup into dependent bases}}
  433. int x = f<NameFromBase>();
  434. };
  435. }
  436. namespace function_template_undef_impl {
  437. template<class T>
  438. void f() {
  439. Undef::staticMethod(); // expected-error {{use of undeclared identifier 'Undef'}}
  440. UndefVar.method(); // expected-error {{use of undeclared identifier 'UndefVar'}}
  441. }
  442. }
  443. namespace PR20716 {
  444. template <template <typename T> class A>
  445. struct B : A<int>
  446. {
  447. XXX x; // expected-error {{unknown type name}}
  448. };
  449. template <typename T>
  450. struct C {};
  451. template <typename T>
  452. using D = C<T>;
  453. template <typename T>
  454. struct E : D<T>
  455. {
  456. XXX x; // expected-error {{unknown type name}}
  457. };
  458. }
  459. namespace PR23810 {
  460. void f(int);
  461. struct Base {
  462. void f(); // expected-note{{must qualify identifier to find this declaration in dependent base class}}
  463. };
  464. template <typename T> struct Template : T {
  465. void member() {
  466. f(); // expected-warning {{found via unqualified lookup into dependent bases}}
  467. }
  468. };
  469. void test() {
  470. Template<Base> x;
  471. x.member(); // expected-note{{requested here}}
  472. };
  473. }
  474. namespace PR23823 {
  475. // Don't delay lookup in SFINAE context.
  476. template <typename T> decltype(g(T())) check(); // expected-note{{candidate template ignored: substitution failure [with T = int]: use of undeclared identifier 'g'}}
  477. decltype(check<int>()) x; // expected-error{{no matching function for call to 'check'}}
  478. void h();
  479. template <typename T> decltype(h(T())) check2(); // expected-note{{candidate template ignored: substitution failure [with T = int]: no matching function for call to 'h'}}
  480. decltype(check2<int>()) y; // expected-error{{no matching function for call to 'check2'}}
  481. }