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 | |