1 | // RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify %s |
2 | // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s |
3 | // RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s |
4 | // RUN: not %clang_cc1 -fsyntax-only -std=c++98 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck --check-prefix=CXX98 %s |
5 | // RUN: not %clang_cc1 -fsyntax-only -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck --check-prefix=CXX11 %s |
6 | // C++0x N2914. |
7 | |
8 | struct X { |
9 | int i; |
10 | static int a; |
11 | enum E { e }; |
12 | }; |
13 | |
14 | using X::i; // expected-error{{using declaration cannot refer to class member}} |
15 | using X::s; // expected-error{{using declaration cannot refer to class member}} |
16 | using X::e; // expected-error{{using declaration cannot refer to class member}} |
17 | using X::E::e; // expected-error{{using declaration cannot refer to class member}} expected-warning 0-1{{C++11}} |
18 | #if __cplusplus < 201103L |
19 | // expected-note@-3 {{use a const variable}} |
20 | // expected-note@-3 {{use a const variable}} |
21 | // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]: |
22 | // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]: |
23 | #else |
24 | // expected-note@-8 {{use a constexpr variable}} |
25 | // expected-note@-8 {{use a constexpr variable}} |
26 | // CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:1-[[@LINE-10]]:6}:"constexpr auto e = " |
27 | // CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:1-[[@LINE-10]]:6}:"constexpr auto e = " |
28 | #endif |
29 | |
30 | void f() { |
31 | using X::i; // expected-error{{using declaration cannot refer to class member}} |
32 | using X::s; // expected-error{{using declaration cannot refer to class member}} |
33 | using X::e; // expected-error{{using declaration cannot refer to class member}} |
34 | using X::E::e; // expected-error{{using declaration cannot refer to class member}} expected-warning 0-1{{C++11}} |
35 | #if __cplusplus < 201103L |
36 | // expected-note@-3 {{use a const variable}} |
37 | // expected-note@-3 {{use a const variable}} |
38 | // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]: |
39 | // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]: |
40 | #else |
41 | // expected-note@-8 {{use a constexpr variable}} |
42 | // expected-note@-8 {{use a constexpr variable}} |
43 | // CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:3-[[@LINE-10]]:8}:"constexpr auto e = " |
44 | // CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:3-[[@LINE-10]]:8}:"constexpr auto e = " |
45 | #endif |
46 | } |
47 | |
48 | namespace PR21933 { |
49 | struct A { int member; }; |
50 | struct B { static int member; }; |
51 | enum C { member }; |
52 | |
53 | template <typename T> |
54 | struct X { |
55 | static void StaticFun() { |
56 | using T::member; // expected-error 2{{class member}} expected-note {{use a reference instead}} |
57 | #if __cplusplus < 201103L |
58 | // expected-error@-2 {{cannot be used prior to '::'}} |
59 | #endif |
60 | (void)member; |
61 | } |
62 | }; |
63 | template<typename T> |
64 | struct Y : T { |
65 | static void StaticFun() { |
66 | using T::member; // expected-error 2{{class member}} expected-note {{use a reference instead}} |
67 | (void)member; |
68 | } |
69 | }; |
70 | |
71 | void f() { |
72 | X<A>::StaticFun(); // expected-note {{instantiation of}} |
73 | X<B>::StaticFun(); // expected-note {{instantiation of}} |
74 | X<C>::StaticFun(); |
75 | #if __cplusplus < 201103L |
76 | // expected-note@-2 {{instantiation of}} |
77 | #endif |
78 | Y<A>::StaticFun(); // expected-note {{instantiation of}} |
79 | Y<B>::StaticFun(); // expected-note {{instantiation of}} |
80 | } |
81 | |
82 | template<typename T, typename U> void value_vs_value() { |
83 | using T::a; // expected-note {{previous}} |
84 | #if __cplusplus < 201103L |
85 | // expected-error@-2 {{cannot be used prior to '::'}} |
86 | #endif |
87 | extern int a(); // expected-error {{different kind of symbol}} |
88 | a(); |
89 | |
90 | extern int b(); // expected-note {{previous}} |
91 | using T::b; // expected-error {{different kind of symbol}} |
92 | b(); |
93 | |
94 | using T::c; // expected-note {{previous}} |
95 | using U::c; // expected-error-re {{redefinition of 'c'{{$}}}} |
96 | c(); |
97 | } |
98 | |
99 | template<typename T, typename U> void value_vs_type() { |
100 | using T::Xt; // expected-note {{previous}} |
101 | typedef struct {} Xt; // expected-error {{different kind of symbol}} |
102 | (void)Xt; |
103 | |
104 | using T::Xs; // expected-note {{hidden by}} |
105 | struct Xs {}; |
106 | (void)Xs; |
107 | Xs xs; // expected-error {{must use 'struct'}} |
108 | |
109 | using T::Xe; // expected-note {{hidden by}} |
110 | enum Xe {}; |
111 | (void)Xe; |
112 | Xe xe; // expected-error {{must use 'enum'}} |
113 | |
114 | typedef struct {} Yt; // expected-note {{candidate}} |
115 | using T::Yt; // eypected-error {{different kind of symbol}} expected-note {{candidate}} |
116 | Yt yt; // expected-error {{ambiguous}} |
117 | |
118 | struct Ys {}; |
119 | using T::Ys; // expected-note {{hidden by}} |
120 | (void)Ys; |
121 | Ys ys; // expected-error {{must use 'struct'}} |
122 | |
123 | enum Ye {}; |
124 | using T::Ye; // expected-note {{hidden by}} |
125 | Ye ye; // expected-error {{must use 'enum'}} |
126 | } |
127 | |
128 | template<typename T> void type() { |
129 | // Must be a class member because T:: can only name a class or enum, |
130 | // and an enum cannot have a type member. |
131 | using typename T::X; // expected-error {{cannot refer to class member}} |
132 | } |
133 | |
134 | namespace N1 { enum E { a, b, c }; } |
135 | namespace N2 { enum E { a, b, c }; } |
136 | void g() { value_vs_value<N1::E, N2::E>(); } |
137 | #if __cplusplus < 201103L |
138 | // expected-note@-2 {{in instantiation of}} |
139 | #endif |
140 | |
141 | #if __cplusplus >= 201402L |
142 | namespace partial_substitute { |
143 | template<typename T> auto f() { |
144 | return [](auto x) { |
145 | using A = typename T::template U<decltype(x)>; |
146 | using A::E::e; |
147 | struct S : A { |
148 | using A::f; |
149 | using typename A::type; |
150 | type f(int) { return e; } |
151 | }; |
152 | return S(); |
153 | }; |
154 | } |
155 | enum Enum { e }; |
156 | struct X { |
157 | template<typename T> struct U { |
158 | int f(int, int); |
159 | using type = int; |
160 | using E = Enum; |
161 | }; |
162 | }; |
163 | int test() { |
164 | auto s = f<X>()(0); |
165 | return s.f(0) + s.f(0, 0); |
166 | } |
167 | |
168 | template<typename T, typename U> auto g() { |
169 | return [](auto x) { |
170 | using X = decltype(x); |
171 | struct S : T::template Q<X>, U::template Q<X> { |
172 | using T::template Q<X>::f; |
173 | using U::template Q<X>::f; |
174 | void h() { f(); } |
175 | void h(int n) { f(n); } |
176 | }; |
177 | return S(); |
178 | }; |
179 | } |
180 | struct A { template<typename> struct Q { int f(); }; }; |
181 | struct B { template<typename> struct Q { int f(int); }; }; |
182 | int test2() { |
183 | auto s = g<A, B>()(0); |
184 | s.f(); |
185 | s.f(0); |
186 | s.h(); |
187 | s.h(0); |
188 | } |
189 | } |
190 | #endif |
191 | |
192 | template<typename T, typename U> struct RepeatedMember : T, U { |
193 | // FIXME: This is the wrong error: we should complain that a member type |
194 | // cannot be redeclared at class scope. |
195 | using typename T::type; // expected-note {{candidate}} |
196 | using typename U::type; // expected-note {{candidate}} |
197 | type x; // expected-error {{ambiguous}} |
198 | }; |
199 | } |
200 | |
201 | struct S { |
202 | static int n; |
203 | struct Q {}; |
204 | enum E {}; |
205 | typedef Q T; |
206 | void f(); |
207 | static void g(); |
208 | }; |
209 | |
210 | using S::n; // expected-error{{class member}} expected-note {{use a reference instead}} |
211 | #if __cplusplus < 201103L |
212 | // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-2]] |
213 | #else |
214 | // CXX11: fix-it:"{{.*}}":{[[@LINE-4]]:1-[[@LINE-4]]:6}:"auto &n = " |
215 | #endif |
216 | |
217 | using S::Q; // expected-error{{class member}} |
218 | #if __cplusplus < 201103L |
219 | // expected-note@-2 {{use a typedef declaration instead}} |
220 | // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:1-[[@LINE-3]]:6}:"typedef" |
221 | // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:11}:" Q" |
222 | #else |
223 | // expected-note@-6 {{use an alias declaration instead}} |
224 | // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:7-[[@LINE-7]]:7}:"Q = " |
225 | #endif |
226 | |
227 | using S::E; // expected-error{{class member}} |
228 | #if __cplusplus < 201103L |
229 | // expected-note@-2 {{use a typedef declaration instead}} |
230 | // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:1-[[@LINE-3]]:6}:"typedef" |
231 | // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:11}:" E" |
232 | #else |
233 | // expected-note@-6 {{use an alias declaration instead}} |
234 | // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:7-[[@LINE-7]]:7}:"E = " |
235 | #endif |
236 | |
237 | using S::T; // expected-error{{class member}} |
238 | #if __cplusplus < 201103L |
239 | // expected-note@-2 {{use a typedef declaration instead}} |
240 | // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:1-[[@LINE-3]]:6}:"typedef" |
241 | // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:11}:" T" |
242 | #else |
243 | // expected-note@-6 {{use an alias declaration instead}} |
244 | // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:7-[[@LINE-7]]:7}:"T = " |
245 | #endif |
246 | |
247 | using S::f; // expected-error{{class member}} |
248 | using S::g; // expected-error{{class member}} |
249 | |
250 | void h() { |
251 | using S::n; // expected-error{{class member}} expected-note {{use a reference instead}} |
252 | #if __cplusplus < 201103L |
253 | // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-2]] |
254 | #else |
255 | // CXX11: fix-it:"{{.*}}":{[[@LINE-4]]:3-[[@LINE-4]]:8}:"auto &n = " |
256 | #endif |
257 | |
258 | using S::Q; // expected-error{{class member}} |
259 | #if __cplusplus < 201103L |
260 | // expected-note@-2 {{use a typedef declaration instead}} |
261 | // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:8}:"typedef" |
262 | // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:13-[[@LINE-4]]:13}:" Q" |
263 | #else |
264 | // expected-note@-6 {{use an alias declaration instead}} |
265 | // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:9-[[@LINE-7]]:9}:"Q = " |
266 | #endif |
267 | |
268 | using S::E; // expected-error{{class member}} |
269 | #if __cplusplus < 201103L |
270 | // expected-note@-2 {{use a typedef declaration instead}} |
271 | // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:8}:"typedef" |
272 | // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:13-[[@LINE-4]]:13}:" E" |
273 | #else |
274 | // expected-note@-6 {{use an alias declaration instead}} |
275 | // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:9-[[@LINE-7]]:9}:"E = " |
276 | #endif |
277 | |
278 | using S::T; // expected-error{{class member}} |
279 | #if __cplusplus < 201103L |
280 | // expected-note@-2 {{use a typedef declaration instead}} |
281 | // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:8}:"typedef" |
282 | // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:13-[[@LINE-4]]:13}:" T" |
283 | #else |
284 | // expected-note@-6 {{use an alias declaration instead}} |
285 | // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:9-[[@LINE-7]]:9}:"T = " |
286 | #endif |
287 | |
288 | using S::f; // expected-error{{class member}} |
289 | using S::g; // expected-error{{class member}} |
290 | } |
291 | |