196 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s2// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s3// RUN: %clang_cc1 -fsyntax-only -verify %s4 5// C++03 [namespace.udecl]p12:6// When a using-declaration brings names from a base class into a7// derived class scope, member functions in the derived class8// override and/or hide member functions with the same name and9// parameter types in a base class (rather than conflicting).10 11template <unsigned n> struct Opaque {};12template <unsigned n> void expect(Opaque<n> _) {} // expected-note 4 {{candidate function template not viable}}13 14// PR572715// This just shouldn't crash.16namespace test0 {17 template<typename> struct RefPtr { };18 template<typename> struct PtrHash {19 static void f() { }20 };21 template<typename T> struct PtrHash<RefPtr<T> > : PtrHash<T*> {22 using PtrHash<T*>::f;23 static void f() { f(); }24 };25}26 27// Simple hiding.28namespace test1 {29 struct Base {30 Opaque<0> foo(Opaque<0>);31 Opaque<0> foo(Opaque<1>);32 Opaque<0> foo(Opaque<2>);33 };34 35 // using before decls36 struct Test0 : Base {37 using Base::foo;38 Opaque<1> foo(Opaque<1>);39 Opaque<1> foo(Opaque<3>);40 41 void test0() { Opaque<0> _ = foo(Opaque<0>()); }42 void test1() { Opaque<1> _ = foo(Opaque<1>()); }43 void test2() { Opaque<0> _ = foo(Opaque<2>()); }44 void test3() { Opaque<1> _ = foo(Opaque<3>()); }45 };46 47 // using after decls48 struct Test1 : Base {49 Opaque<1> foo(Opaque<1>);50 Opaque<1> foo(Opaque<3>);51 using Base::foo;52 53 void test0() { Opaque<0> _ = foo(Opaque<0>()); }54 void test1() { Opaque<1> _ = foo(Opaque<1>()); }55 void test2() { Opaque<0> _ = foo(Opaque<2>()); }56 void test3() { Opaque<1> _ = foo(Opaque<3>()); }57 };58 59 // using between decls60 struct Test2 : Base {61 Opaque<1> foo(Opaque<0>);62 using Base::foo;63 Opaque<1> foo(Opaque<2>);64 Opaque<1> foo(Opaque<3>);65 66 void test0() { Opaque<1> _ = foo(Opaque<0>()); }67 void test1() { Opaque<0> _ = foo(Opaque<1>()); }68 void test2() { Opaque<1> _ = foo(Opaque<2>()); }69 void test3() { Opaque<1> _ = foo(Opaque<3>()); }70 };71}72 73// Crazy dependent hiding.74namespace test2 {75 struct Base {76 void foo(int);77 };78 79 template <typename T> struct Derived1 : Base {80 using Base::foo;81 void foo(T);82 83 void testUnresolved(int i) { foo(i); }84 };85 86 void test0(int i) {87 Derived1<int> d1;88 d1.foo(i);89 d1.testUnresolved(i);90 }91 92 // Same thing, except with the order of members reversed.93 template <typename T> struct Derived2 : Base {94 void foo(T);95 using Base::foo;96 97 void testUnresolved(int i) { foo(i); }98 };99 100 void test1(int i) {101 Derived2<int> d2;102 d2.foo(i);103 d2.testUnresolved(i);104 }105}106 107// Hiding of member templates.108namespace test3 {109 struct Base {110 template <class T> Opaque<0> foo() { return Opaque<0>(); }111 template <int n> Opaque<1> foo() { return Opaque<1>(); }112 };113 114 struct Derived1 : Base {115 using Base::foo;116 template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}}117 };118 119 struct Derived2 : Base {120 template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}}121 using Base::foo;122 };123 124 struct Derived3 : Base {125 using Base::foo;126 template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}}127 };128 129 struct Derived4 : Base {130 template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}}131 using Base::foo;132 };133 134 void test() {135 expect<0>(Base().foo<int>());136 expect<1>(Base().foo<0>());137 expect<0>(Derived1().foo<int>()); // expected-error {{no matching member function for call to 'foo'}} expected-error {{no matching function for call to 'expect'}}138 expect<2>(Derived1().foo<0>());139 expect<0>(Derived2().foo<int>()); // expected-error {{no matching member function for call to 'foo'}} expected-error {{no matching function for call to 'expect'}}140 expect<2>(Derived2().foo<0>());141 expect<3>(Derived3().foo<int>());142 expect<1>(Derived3().foo<0>()); // expected-error {{no matching member function for call to 'foo'}} expected-error {{no matching function for call to 'expect'}}143 expect<3>(Derived4().foo<int>());144 expect<1>(Derived4().foo<0>()); // expected-error {{no matching member function for call to 'foo'}} expected-error {{no matching function for call to 'expect'}}145 }146}147 148// PR7384: access control for member templates.149namespace test4 {150 class Base {151 protected:152 template<typename T> void foo(T);153 template<typename T> void bar(T); // expected-note {{declared protected here}}154 };155 156 struct Derived : Base {157 using Base::foo;158 };159 160 void test() {161 Derived d;162 d.foo<int>(3);163 d.bar<int>(3); // expected-error {{'bar' is a protected member}}164 }165}166 167namespace test5 {168 struct Derived;169 struct Base {170 void operator=(const Derived&);171 };172 struct Derived : Base {173 // Hidden by implicit derived class operator.174 using Base::operator=;175 };176 void f(Derived d) {177 d = d;178 }179}180 181#if __cplusplus >= 201103L182namespace test6 {183 struct Derived;184 struct Base {185 void operator=(Derived&&);186 };187 struct Derived : Base {188 // Hidden by implicit derived class operator.189 using Base::operator=;190 };191 void f(Derived d) {192 d = Derived();193 }194}195#endif196