1 // RUN: %clang_cc1 -fsyntax-only -verify %s 2 3 // C++03 [namespace.udecl]p12: 4 // When a using-declaration brings names from a base class into a 5 // derived class scope, member functions in the derived class 6 // override and/or hide member functions with the same name and 7 // parameter types in a base class (rather than conflicting). 8 9 template <unsigned n> struct Opaque {}; expect(Opaque<n> _)10template <unsigned n> void expect(Opaque<n> _) {} 11 12 // PR5727 13 // This just shouldn't crash. 14 namespace test0 { 15 template<typename> struct RefPtr { }; 16 template<typename> struct PtrHash { ftest0::PtrHash17 static void f() { } 18 }; 19 template<typename T> struct PtrHash<RefPtr<T> > : PtrHash<T*> { 20 using PtrHash<T*>::f; ftest0::PtrHash21 static void f() { f(); } 22 }; 23 } 24 25 // Simple hiding. 26 namespace test1 { 27 struct Base { 28 Opaque<0> foo(Opaque<0>); 29 Opaque<0> foo(Opaque<1>); 30 Opaque<0> foo(Opaque<2>); 31 }; 32 33 // using before decls 34 struct Test0 : Base { 35 using Base::foo; 36 Opaque<1> foo(Opaque<1>); 37 Opaque<1> foo(Opaque<3>); 38 test0test1::Test039 void test0() { Opaque<0> _ = foo(Opaque<0>()); } test1test1::Test040 void test1() { Opaque<1> _ = foo(Opaque<1>()); } test2test1::Test041 void test2() { Opaque<0> _ = foo(Opaque<2>()); } test3test1::Test042 void test3() { Opaque<1> _ = foo(Opaque<3>()); } 43 }; 44 45 // using after decls 46 struct Test1 : Base { 47 Opaque<1> foo(Opaque<1>); 48 Opaque<1> foo(Opaque<3>); 49 using Base::foo; 50 test0test1::Test151 void test0() { Opaque<0> _ = foo(Opaque<0>()); } test1test1::Test152 void test1() { Opaque<1> _ = foo(Opaque<1>()); } test2test1::Test153 void test2() { Opaque<0> _ = foo(Opaque<2>()); } test3test1::Test154 void test3() { Opaque<1> _ = foo(Opaque<3>()); } 55 }; 56 57 // using between decls 58 struct Test2 : Base { 59 Opaque<1> foo(Opaque<0>); 60 using Base::foo; 61 Opaque<1> foo(Opaque<2>); 62 Opaque<1> foo(Opaque<3>); 63 test0test1::Test264 void test0() { Opaque<1> _ = foo(Opaque<0>()); } test1test1::Test265 void test1() { Opaque<0> _ = foo(Opaque<1>()); } test2test1::Test266 void test2() { Opaque<1> _ = foo(Opaque<2>()); } test3test1::Test267 void test3() { Opaque<1> _ = foo(Opaque<3>()); } 68 }; 69 } 70 71 // Crazy dependent hiding. 72 namespace test2 { 73 struct Base { 74 void foo(int); 75 }; 76 77 template <typename T> struct Derived1 : Base { 78 using Base::foo; 79 void foo(T); 80 testUnresolvedtest2::Derived181 void testUnresolved(int i) { foo(i); } 82 }; 83 test0(int i)84 void test0(int i) { 85 Derived1<int> d1; 86 d1.foo(i); 87 d1.testUnresolved(i); 88 } 89 90 // Same thing, except with the order of members reversed. 91 template <typename T> struct Derived2 : Base { 92 void foo(T); 93 using Base::foo; 94 testUnresolvedtest2::Derived295 void testUnresolved(int i) { foo(i); } 96 }; 97 test1(int i)98 void test1(int i) { 99 Derived2<int> d2; 100 d2.foo(i); 101 d2.testUnresolved(i); 102 } 103 } 104 105 // Hiding of member templates. 106 namespace test3 { 107 struct Base { footest3::Base108 template <class T> Opaque<0> foo() { return Opaque<0>(); } footest3::Base109 template <int n> Opaque<1> foo() { return Opaque<1>(); } 110 }; 111 112 struct Derived1 : Base { 113 using Base::foo; footest3::Derived1114 template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}} 115 }; 116 117 struct Derived2 : Base { footest3::Derived2118 template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}} 119 using Base::foo; 120 }; 121 122 struct Derived3 : Base { 123 using Base::foo; footest3::Derived3124 template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}} 125 }; 126 127 struct Derived4 : Base { footest3::Derived4128 template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}} 129 using Base::foo; 130 }; 131 test()132 void test() { 133 expect<0>(Base().foo<int>()); 134 expect<1>(Base().foo<0>()); 135 expect<0>(Derived1().foo<int>()); // expected-error {{no matching member function for call to 'foo'}} 136 expect<2>(Derived1().foo<0>()); 137 expect<0>(Derived2().foo<int>()); // expected-error {{no matching member function for call to 'foo'}} 138 expect<2>(Derived2().foo<0>()); 139 expect<3>(Derived3().foo<int>()); 140 expect<1>(Derived3().foo<0>()); // expected-error {{no matching member function for call to 'foo'}} 141 expect<3>(Derived4().foo<int>()); 142 expect<1>(Derived4().foo<0>()); // expected-error {{no matching member function for call to 'foo'}} 143 } 144 } 145 146 // PR7384: access control for member templates. 147 namespace test4 { 148 class Base { 149 protected: 150 template<typename T> void foo(T); 151 template<typename T> void bar(T); // expected-note {{declared protected here}} 152 }; 153 154 struct Derived : Base { 155 using Base::foo; 156 }; 157 test()158 void test() { 159 Derived d; 160 d.foo<int>(3); 161 d.bar<int>(3); // expected-error {{'bar' is a protected member}} 162 } 163 } 164