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