1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s 2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s 3 // RUN: %clang_cc1 -fsyntax-only -verify %s 4 5 // C++03 [namespace.udecl]p12: 6 // When a using-declaration brings names from a base class into a 7 // derived class scope, member functions in the derived class 8 // override and/or hide member functions with the same name and 9 // parameter types in a base class (rather than conflicting). 10 11 template <unsigned n> struct Opaque {}; 12 template <unsigned n> void expect(Opaque<n> _) {} 13 14 // PR5727 15 // This just shouldn't crash. 16 namespace 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. 28 namespace 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 decls 36 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 decls 48 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 decls 60 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. 74 namespace 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. 108 namespace 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'}} 138 expect<2>(Derived1().foo<0>()); 139 expect<0>(Derived2().foo<int>()); // expected-error {{no matching member function for call to 'foo'}} 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'}} 143 expect<3>(Derived4().foo<int>()); 144 expect<1>(Derived4().foo<0>()); // expected-error {{no matching member function for call to 'foo'}} 145 } 146 } 147 148 // PR7384: access control for member templates. 149 namespace 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 167 namespace 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 >= 201103L 182 namespace 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 #endif 196