annotate clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp @ 150:1d019706d866

LLVM10
author anatofuz
date Thu, 13 Feb 2020 15:10:13 +0900
parents
children 0572611fdcc8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++1y -fms-compatibility -fno-spell-checking -fsyntax-only -verify %s
anatofuz
parents:
diff changeset
2
anatofuz
parents:
diff changeset
3
anatofuz
parents:
diff changeset
4 template <class T>
anatofuz
parents:
diff changeset
5 class A {
anatofuz
parents:
diff changeset
6 public:
anatofuz
parents:
diff changeset
7 void f(T a) { }// expected-note 2{{must qualify identifier to find this declaration in dependent base class}}
anatofuz
parents:
diff changeset
8 void g();// expected-note 2{{must qualify identifier to find this declaration in dependent base class}}
anatofuz
parents:
diff changeset
9 };
anatofuz
parents:
diff changeset
10
anatofuz
parents:
diff changeset
11 template <class T>
anatofuz
parents:
diff changeset
12 class B : public A<T> {
anatofuz
parents:
diff changeset
13 public:
anatofuz
parents:
diff changeset
14 void z(T a)
anatofuz
parents:
diff changeset
15 {
anatofuz
parents:
diff changeset
16 f(a); // expected-warning 2{{use of identifier 'f' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
anatofuz
parents:
diff changeset
17 g(); // expected-warning 2{{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
anatofuz
parents:
diff changeset
18 }
anatofuz
parents:
diff changeset
19 };
anatofuz
parents:
diff changeset
20
anatofuz
parents:
diff changeset
21 template class B<int>; // expected-note {{requested here}}
anatofuz
parents:
diff changeset
22 template class B<char>; // expected-note {{requested here}}
anatofuz
parents:
diff changeset
23
anatofuz
parents:
diff changeset
24 void test()
anatofuz
parents:
diff changeset
25 {
anatofuz
parents:
diff changeset
26 B<int> b;
anatofuz
parents:
diff changeset
27 b.z(3);
anatofuz
parents:
diff changeset
28 }
anatofuz
parents:
diff changeset
29
anatofuz
parents:
diff changeset
30 struct A2 {
anatofuz
parents:
diff changeset
31 template<class T> void f(T) {
anatofuz
parents:
diff changeset
32 XX; //expected-error {{use of undeclared identifier 'XX'}}
anatofuz
parents:
diff changeset
33 A2::XX; //expected-error {{no member named 'XX' in 'A2'}}
anatofuz
parents:
diff changeset
34 }
anatofuz
parents:
diff changeset
35 };
anatofuz
parents:
diff changeset
36 template void A2::f(int);
anatofuz
parents:
diff changeset
37
anatofuz
parents:
diff changeset
38 template<class T0>
anatofuz
parents:
diff changeset
39 struct A3 {
anatofuz
parents:
diff changeset
40 template<class T1> void f(T1) {
anatofuz
parents:
diff changeset
41 XX; //expected-error {{use of undeclared identifier 'XX'}}
anatofuz
parents:
diff changeset
42 }
anatofuz
parents:
diff changeset
43 };
anatofuz
parents:
diff changeset
44 template void A3<int>::f(int);
anatofuz
parents:
diff changeset
45
anatofuz
parents:
diff changeset
46 template<class T0>
anatofuz
parents:
diff changeset
47 struct A4 {
anatofuz
parents:
diff changeset
48 void f(char) {
anatofuz
parents:
diff changeset
49 XX; //expected-error {{use of undeclared identifier 'XX'}}
anatofuz
parents:
diff changeset
50 }
anatofuz
parents:
diff changeset
51 };
anatofuz
parents:
diff changeset
52 template class A4<int>;
anatofuz
parents:
diff changeset
53
anatofuz
parents:
diff changeset
54
anatofuz
parents:
diff changeset
55 namespace lookup_dependent_bases_id_expr {
anatofuz
parents:
diff changeset
56
anatofuz
parents:
diff changeset
57 template<class T> class A {
anatofuz
parents:
diff changeset
58 public:
anatofuz
parents:
diff changeset
59 int var;
anatofuz
parents:
diff changeset
60 };
anatofuz
parents:
diff changeset
61
anatofuz
parents:
diff changeset
62
anatofuz
parents:
diff changeset
63 template<class T>
anatofuz
parents:
diff changeset
64 class B : public A<T> {
anatofuz
parents:
diff changeset
65 public:
anatofuz
parents:
diff changeset
66 void f() {
anatofuz
parents:
diff changeset
67 var = 3; // expected-warning {{use of undeclared identifier 'var'; unqualified lookup into dependent bases of class template 'B' is a Microsoft extension}}
anatofuz
parents:
diff changeset
68 }
anatofuz
parents:
diff changeset
69 };
anatofuz
parents:
diff changeset
70
anatofuz
parents:
diff changeset
71 template class B<int>;
anatofuz
parents:
diff changeset
72
anatofuz
parents:
diff changeset
73 }
anatofuz
parents:
diff changeset
74
anatofuz
parents:
diff changeset
75
anatofuz
parents:
diff changeset
76
anatofuz
parents:
diff changeset
77 namespace lookup_dependent_base_class_static_function {
anatofuz
parents:
diff changeset
78
anatofuz
parents:
diff changeset
79 template <class T>
anatofuz
parents:
diff changeset
80 class A {
anatofuz
parents:
diff changeset
81 public:
anatofuz
parents:
diff changeset
82 static void static_func();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
anatofuz
parents:
diff changeset
83 void func();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
anatofuz
parents:
diff changeset
84 };
anatofuz
parents:
diff changeset
85
anatofuz
parents:
diff changeset
86
anatofuz
parents:
diff changeset
87 template <class T>
anatofuz
parents:
diff changeset
88 class B : public A<T> {
anatofuz
parents:
diff changeset
89 public:
anatofuz
parents:
diff changeset
90 static void z2(){
anatofuz
parents:
diff changeset
91 static_func(); // expected-warning {{use of identifier 'static_func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
anatofuz
parents:
diff changeset
92 func(); // expected-warning {{use of identifier 'func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-error {{call to non-static member function without an object argument}}
anatofuz
parents:
diff changeset
93 }
anatofuz
parents:
diff changeset
94 };
anatofuz
parents:
diff changeset
95 template class B<int>; // expected-note {{requested here}}
anatofuz
parents:
diff changeset
96
anatofuz
parents:
diff changeset
97 }
anatofuz
parents:
diff changeset
98
anatofuz
parents:
diff changeset
99
anatofuz
parents:
diff changeset
100
anatofuz
parents:
diff changeset
101 namespace lookup_dependent_base_class_default_argument {
anatofuz
parents:
diff changeset
102
anatofuz
parents:
diff changeset
103 template<class T>
anatofuz
parents:
diff changeset
104 class A {
anatofuz
parents:
diff changeset
105 public:
anatofuz
parents:
diff changeset
106 static int f1(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
anatofuz
parents:
diff changeset
107 int f2(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
anatofuz
parents:
diff changeset
108 };
anatofuz
parents:
diff changeset
109
anatofuz
parents:
diff changeset
110 template<class T>
anatofuz
parents:
diff changeset
111 class B : public A<T> {
anatofuz
parents:
diff changeset
112 public:
anatofuz
parents:
diff changeset
113 void g1(int p = f1());// expected-warning {{use of identifier 'f1' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
anatofuz
parents:
diff changeset
114 void g2(int p = f2());// expected-warning {{use of identifier 'f2' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-error {{call to non-static member function without an object argument}}
anatofuz
parents:
diff changeset
115 };
anatofuz
parents:
diff changeset
116
anatofuz
parents:
diff changeset
117 void foo()
anatofuz
parents:
diff changeset
118 {
anatofuz
parents:
diff changeset
119 B<int> b;
anatofuz
parents:
diff changeset
120 b.g1(); // expected-note {{required here}}
anatofuz
parents:
diff changeset
121 b.g2(); // expected-note {{required here}}
anatofuz
parents:
diff changeset
122 }
anatofuz
parents:
diff changeset
123
anatofuz
parents:
diff changeset
124 }
anatofuz
parents:
diff changeset
125
anatofuz
parents:
diff changeset
126
anatofuz
parents:
diff changeset
127 namespace lookup_dependent_base_class_friend {
anatofuz
parents:
diff changeset
128
anatofuz
parents:
diff changeset
129 template <class T>
anatofuz
parents:
diff changeset
130 class B {
anatofuz
parents:
diff changeset
131 public:
anatofuz
parents:
diff changeset
132 static void g(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
anatofuz
parents:
diff changeset
133 };
anatofuz
parents:
diff changeset
134
anatofuz
parents:
diff changeset
135 template <class T>
anatofuz
parents:
diff changeset
136 class A : public B<T> {
anatofuz
parents:
diff changeset
137 public:
anatofuz
parents:
diff changeset
138 friend void foo(A<T> p){
anatofuz
parents:
diff changeset
139 g(); // expected-warning {{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
anatofuz
parents:
diff changeset
140 }
anatofuz
parents:
diff changeset
141 };
anatofuz
parents:
diff changeset
142
anatofuz
parents:
diff changeset
143 int main2()
anatofuz
parents:
diff changeset
144 {
anatofuz
parents:
diff changeset
145 A<int> a;
anatofuz
parents:
diff changeset
146 foo(a); // expected-note {{requested here}}
anatofuz
parents:
diff changeset
147 }
anatofuz
parents:
diff changeset
148
anatofuz
parents:
diff changeset
149 }
anatofuz
parents:
diff changeset
150
anatofuz
parents:
diff changeset
151
anatofuz
parents:
diff changeset
152 namespace lookup_dependent_base_no_typo_correction {
anatofuz
parents:
diff changeset
153
anatofuz
parents:
diff changeset
154 class C {
anatofuz
parents:
diff changeset
155 public:
anatofuz
parents:
diff changeset
156 int m_hWnd;
anatofuz
parents:
diff changeset
157 };
anatofuz
parents:
diff changeset
158
anatofuz
parents:
diff changeset
159 template <class T>
anatofuz
parents:
diff changeset
160 class A : public T {
anatofuz
parents:
diff changeset
161 public:
anatofuz
parents:
diff changeset
162 void f(int hWnd) {
anatofuz
parents:
diff changeset
163 m_hWnd = 1; // expected-warning {{use of undeclared identifier 'm_hWnd'; unqualified lookup into dependent bases of class template 'A' is a Microsoft extension}}
anatofuz
parents:
diff changeset
164 }
anatofuz
parents:
diff changeset
165 };
anatofuz
parents:
diff changeset
166
anatofuz
parents:
diff changeset
167 template class A<C>;
anatofuz
parents:
diff changeset
168
anatofuz
parents:
diff changeset
169 }
anatofuz
parents:
diff changeset
170
anatofuz
parents:
diff changeset
171 namespace PR12701 {
anatofuz
parents:
diff changeset
172
anatofuz
parents:
diff changeset
173 class A {};
anatofuz
parents:
diff changeset
174 class B {};
anatofuz
parents:
diff changeset
175
anatofuz
parents:
diff changeset
176 template <class T>
anatofuz
parents:
diff changeset
177 class Base {
anatofuz
parents:
diff changeset
178 public:
anatofuz
parents:
diff changeset
179 bool base_fun(void* p) { return false; } // expected-note {{must qualify identifier to find this declaration in dependent base class}}
anatofuz
parents:
diff changeset
180 operator T*() const { return 0; }
anatofuz
parents:
diff changeset
181 };
anatofuz
parents:
diff changeset
182
anatofuz
parents:
diff changeset
183 template <class T>
anatofuz
parents:
diff changeset
184 class Container : public Base<T> {
anatofuz
parents:
diff changeset
185 public:
anatofuz
parents:
diff changeset
186 template <typename S>
anatofuz
parents:
diff changeset
187 bool operator=(const Container<S>& rhs) {
anatofuz
parents:
diff changeset
188 return base_fun(rhs); // expected-warning {{use of identifier 'base_fun' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
anatofuz
parents:
diff changeset
189 }
anatofuz
parents:
diff changeset
190 };
anatofuz
parents:
diff changeset
191
anatofuz
parents:
diff changeset
192 void f() {
anatofuz
parents:
diff changeset
193 Container<A> text_provider;
anatofuz
parents:
diff changeset
194 Container<B> text_provider2;
anatofuz
parents:
diff changeset
195 text_provider2 = text_provider; // expected-note {{in instantiation of function template specialization}}
anatofuz
parents:
diff changeset
196 }
anatofuz
parents:
diff changeset
197
anatofuz
parents:
diff changeset
198 } // namespace PR12701
anatofuz
parents:
diff changeset
199
anatofuz
parents:
diff changeset
200 namespace PR16014 {
anatofuz
parents:
diff changeset
201
anatofuz
parents:
diff changeset
202 struct A {
anatofuz
parents:
diff changeset
203 int a;
anatofuz
parents:
diff changeset
204 static int sa;
anatofuz
parents:
diff changeset
205 };
anatofuz
parents:
diff changeset
206 template <typename T> struct B : T {
anatofuz
parents:
diff changeset
207 int foo() { return a; } // expected-warning {{lookup into dependent bases}}
anatofuz
parents:
diff changeset
208 int *bar() { return &a; } // expected-warning {{lookup into dependent bases}}
anatofuz
parents:
diff changeset
209 int baz() { return T::a; }
anatofuz
parents:
diff changeset
210 int T::*qux() { return &T::a; }
anatofuz
parents:
diff changeset
211 static int T::*stuff() { return &T::a; }
anatofuz
parents:
diff changeset
212 static int stuff1() { return T::sa; }
anatofuz
parents:
diff changeset
213 static int *stuff2() { return &T::sa; }
anatofuz
parents:
diff changeset
214 static int stuff3() { return sa; } // expected-warning {{lookup into dependent bases}}
anatofuz
parents:
diff changeset
215 static int *stuff4() { return &sa; } // expected-warning {{lookup into dependent bases}}
anatofuz
parents:
diff changeset
216 };
anatofuz
parents:
diff changeset
217
anatofuz
parents:
diff changeset
218 template <typename T> struct C : T {
anatofuz
parents:
diff changeset
219 int foo() { return b; } // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
anatofuz
parents:
diff changeset
220 int *bar() { return &b; } // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
anatofuz
parents:
diff changeset
221 int baz() { return T::b; } // expected-error {{no member named 'b' in 'PR16014::A'}}
anatofuz
parents:
diff changeset
222 int T::*qux() { return &T::b; } // expected-error {{no member named 'b' in 'PR16014::A'}}
anatofuz
parents:
diff changeset
223 int T::*fuz() { return &U::a; } // expected-error {{use of undeclared identifier 'U'}} \
anatofuz
parents:
diff changeset
224 // expected-warning {{unqualified lookup into dependent bases of class template 'C'}}
anatofuz
parents:
diff changeset
225 };
anatofuz
parents:
diff changeset
226
anatofuz
parents:
diff changeset
227 template struct B<A>;
anatofuz
parents:
diff changeset
228 template struct C<A>; // expected-note-re 1+ {{in instantiation of member function 'PR16014::C<PR16014::A>::{{.*}}' requested here}}
anatofuz
parents:
diff changeset
229
anatofuz
parents:
diff changeset
230 template <typename T> struct D : T {
anatofuz
parents:
diff changeset
231 struct Inner {
anatofuz
parents:
diff changeset
232 int foo() {
anatofuz
parents:
diff changeset
233 // FIXME: MSVC can find this in D's base T! Even worse, if ::sa exists,
anatofuz
parents:
diff changeset
234 // clang will use it instead.
anatofuz
parents:
diff changeset
235 return sa; // expected-error {{use of undeclared identifier 'sa'}}
anatofuz
parents:
diff changeset
236 }
anatofuz
parents:
diff changeset
237 };
anatofuz
parents:
diff changeset
238 };
anatofuz
parents:
diff changeset
239 template struct D<A>;
anatofuz
parents:
diff changeset
240
anatofuz
parents:
diff changeset
241 }
anatofuz
parents:
diff changeset
242
anatofuz
parents:
diff changeset
243 namespace PR19233 {
anatofuz
parents:
diff changeset
244 template <class T>
anatofuz
parents:
diff changeset
245 struct A : T {
anatofuz
parents:
diff changeset
246 void foo() {
anatofuz
parents:
diff changeset
247 ::undef(); // expected-error {{no member named 'undef' in the global namespace}}
anatofuz
parents:
diff changeset
248 }
anatofuz
parents:
diff changeset
249 void bar() {
anatofuz
parents:
diff changeset
250 ::UndefClass::undef(); // expected-error {{no member named 'UndefClass' in the global namespace}}
anatofuz
parents:
diff changeset
251 }
anatofuz
parents:
diff changeset
252 void baz() {
anatofuz
parents:
diff changeset
253 B::qux(); // expected-error {{use of undeclared identifier 'B'}} \
anatofuz
parents:
diff changeset
254 // expected-warning {{unqualified lookup into dependent bases of class template 'A'}}
anatofuz
parents:
diff changeset
255 }
anatofuz
parents:
diff changeset
256 };
anatofuz
parents:
diff changeset
257
anatofuz
parents:
diff changeset
258 struct B { void qux(); };
anatofuz
parents:
diff changeset
259 struct C : B { };
anatofuz
parents:
diff changeset
260 template struct A<C>; // No error! B is a base of A<C>, and qux is available.
anatofuz
parents:
diff changeset
261
anatofuz
parents:
diff changeset
262 struct D { };
anatofuz
parents:
diff changeset
263 template struct A<D>; // expected-note {{in instantiation of member function 'PR19233::A<PR19233::D>::baz' requested here}}
anatofuz
parents:
diff changeset
264
anatofuz
parents:
diff changeset
265 }
anatofuz
parents:
diff changeset
266
anatofuz
parents:
diff changeset
267 namespace nonmethod_missing_this {
anatofuz
parents:
diff changeset
268 template <typename T> struct Base { int y = 42; };
anatofuz
parents:
diff changeset
269 template <typename T> struct Derived : Base<T> {
anatofuz
parents:
diff changeset
270 int x = y; // expected-warning {{lookup into dependent bases}}
anatofuz
parents:
diff changeset
271 auto foo(int j) -> decltype(y * j) { // expected-warning {{lookup into dependent bases}}
anatofuz
parents:
diff changeset
272 return y * j; // expected-warning {{lookup into dependent bases}}
anatofuz
parents:
diff changeset
273 }
anatofuz
parents:
diff changeset
274 int bar() {
anatofuz
parents:
diff changeset
275 return [&] { return y; }(); // expected-warning {{lookup into dependent bases}}
anatofuz
parents:
diff changeset
276 }
anatofuz
parents:
diff changeset
277 };
anatofuz
parents:
diff changeset
278 template struct Derived<int>;
anatofuz
parents:
diff changeset
279 }
anatofuz
parents:
diff changeset
280
anatofuz
parents:
diff changeset
281 namespace typedef_in_base {
anatofuz
parents:
diff changeset
282 template <typename T> struct A { typedef T NameFromBase; };
anatofuz
parents:
diff changeset
283 template <typename T> struct B : A<T> {
anatofuz
parents:
diff changeset
284 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
anatofuz
parents:
diff changeset
285 };
anatofuz
parents:
diff changeset
286 static_assert(sizeof(B<int>) == 4, "");
anatofuz
parents:
diff changeset
287 }
anatofuz
parents:
diff changeset
288
anatofuz
parents:
diff changeset
289 namespace struct_in_base {
anatofuz
parents:
diff changeset
290 template <typename T> struct A { struct NameFromBase {}; };
anatofuz
parents:
diff changeset
291 template <typename T> struct B : A<T> {
anatofuz
parents:
diff changeset
292 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
anatofuz
parents:
diff changeset
293 };
anatofuz
parents:
diff changeset
294 static_assert(sizeof(B<int>) == 1, "");
anatofuz
parents:
diff changeset
295 }
anatofuz
parents:
diff changeset
296
anatofuz
parents:
diff changeset
297 namespace enum_in_base {
anatofuz
parents:
diff changeset
298 template <typename T> struct A { enum NameFromBase { X }; };
anatofuz
parents:
diff changeset
299 template <typename T> struct B : A<T> {
anatofuz
parents:
diff changeset
300 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
anatofuz
parents:
diff changeset
301 };
anatofuz
parents:
diff changeset
302 static_assert(sizeof(B<int>) == sizeof(A<int>::NameFromBase), "");
anatofuz
parents:
diff changeset
303 }
anatofuz
parents:
diff changeset
304
anatofuz
parents:
diff changeset
305 namespace two_types_in_base {
anatofuz
parents:
diff changeset
306 template <typename T> struct A { typedef T NameFromBase; }; // expected-note {{member found by ambiguous name lookup}}
anatofuz
parents:
diff changeset
307 template <typename T> struct B { struct NameFromBase { T m; }; }; // expected-note {{member found by ambiguous name lookup}}
anatofuz
parents:
diff changeset
308 template <typename T> struct C : A<T>, B<T> {
anatofuz
parents:
diff changeset
309 NameFromBase m; // expected-error {{member 'NameFromBase' found in multiple base classes of different types}} expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
anatofuz
parents:
diff changeset
310 };
anatofuz
parents:
diff changeset
311 static_assert(sizeof(C<int>) != 0, ""); // expected-note {{in instantiation of template class 'two_types_in_base::C<int>' requested here}}
anatofuz
parents:
diff changeset
312 }
anatofuz
parents:
diff changeset
313
anatofuz
parents:
diff changeset
314 namespace type_and_decl_in_base {
anatofuz
parents:
diff changeset
315 template <typename T> struct A { typedef T NameFromBase; };
anatofuz
parents:
diff changeset
316 template <typename T> struct B { static const T NameFromBase = 42; };
anatofuz
parents:
diff changeset
317 template <typename T> struct C : A<T>, B<T> {
anatofuz
parents:
diff changeset
318 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
anatofuz
parents:
diff changeset
319 };
anatofuz
parents:
diff changeset
320 }
anatofuz
parents:
diff changeset
321
anatofuz
parents:
diff changeset
322 namespace classify_type_from_base {
anatofuz
parents:
diff changeset
323 template <typename T> struct A { struct NameFromBase {}; };
anatofuz
parents:
diff changeset
324 template <typename T> struct B : A<T> {
anatofuz
parents:
diff changeset
325 A<NameFromBase> m; // expected-warning {{found via unqualified lookup into dependent bases}}
anatofuz
parents:
diff changeset
326 };
anatofuz
parents:
diff changeset
327 }
anatofuz
parents:
diff changeset
328
anatofuz
parents:
diff changeset
329 namespace classify_nontype_from_base {
anatofuz
parents:
diff changeset
330 // MSVC does not do lookup of non-type declarations from dependent template base
anatofuz
parents:
diff changeset
331 // classes. The extra lookup only applies to types.
anatofuz
parents:
diff changeset
332 template <typename T> struct A { void NameFromBase() {} };
anatofuz
parents:
diff changeset
333 template <void (*F)()> struct B { };
anatofuz
parents:
diff changeset
334 template <typename T> struct C : A<T> {
anatofuz
parents:
diff changeset
335 B<C::NameFromBase> a; // correct
anatofuz
parents:
diff changeset
336 B<NameFromBase> b; // expected-error {{use of undeclared identifier 'NameFromBase'}}
anatofuz
parents:
diff changeset
337 };
anatofuz
parents:
diff changeset
338 }
anatofuz
parents:
diff changeset
339
anatofuz
parents:
diff changeset
340 namespace template_in_base {
anatofuz
parents:
diff changeset
341 template <typename T> struct A {
anatofuz
parents:
diff changeset
342 template <typename U> struct NameFromBase { U x; };
anatofuz
parents:
diff changeset
343 };
anatofuz
parents:
diff changeset
344 template <typename T> struct B : A<T> {
anatofuz
parents:
diff changeset
345 // Correct form.
anatofuz
parents:
diff changeset
346 typename B::template NameFromBase<T> m;
anatofuz
parents:
diff changeset
347 };
anatofuz
parents:
diff changeset
348 template <typename T> struct C : A<T> {
anatofuz
parents:
diff changeset
349 // Incorrect form.
anatofuz
parents:
diff changeset
350 NameFromBase<T> m; // expected-error {{no template named 'NameFromBase'}}
anatofuz
parents:
diff changeset
351 };
anatofuz
parents:
diff changeset
352 }
anatofuz
parents:
diff changeset
353
anatofuz
parents:
diff changeset
354 namespace type_in_inner_class_in_base {
anatofuz
parents:
diff changeset
355 template <typename T>
anatofuz
parents:
diff changeset
356 struct A {
anatofuz
parents:
diff changeset
357 struct B { typedef T NameFromBase; };
anatofuz
parents:
diff changeset
358 };
anatofuz
parents:
diff changeset
359 template <typename T>
anatofuz
parents:
diff changeset
360 struct C : A<T>::B { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
anatofuz
parents:
diff changeset
361 }
anatofuz
parents:
diff changeset
362
anatofuz
parents:
diff changeset
363 namespace type_in_inner_template_class_in_base {
anatofuz
parents:
diff changeset
364 template <typename T>
anatofuz
parents:
diff changeset
365 struct A {
anatofuz
parents:
diff changeset
366 template <typename U> struct B { typedef U InnerType; };
anatofuz
parents:
diff changeset
367 };
anatofuz
parents:
diff changeset
368 template <typename T>
anatofuz
parents:
diff changeset
369 struct C : A<T>::template B<T> {
anatofuz
parents:
diff changeset
370 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
anatofuz
parents:
diff changeset
371 };
anatofuz
parents:
diff changeset
372 }
anatofuz
parents:
diff changeset
373
anatofuz
parents:
diff changeset
374 namespace have_nondependent_base {
anatofuz
parents:
diff changeset
375 template <typename T>
anatofuz
parents:
diff changeset
376 struct A {
anatofuz
parents:
diff changeset
377 // Nothing, lookup should fail.
anatofuz
parents:
diff changeset
378 };
anatofuz
parents:
diff changeset
379 template <typename T>
anatofuz
parents:
diff changeset
380 struct B : A<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
anatofuz
parents:
diff changeset
381 struct C : A<int> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
anatofuz
parents:
diff changeset
382 }
anatofuz
parents:
diff changeset
383
anatofuz
parents:
diff changeset
384 namespace type_in_base_of_dependent_base {
anatofuz
parents:
diff changeset
385 struct A { typedef int NameFromBase; };
anatofuz
parents:
diff changeset
386 template <typename T>
anatofuz
parents:
diff changeset
387 struct B : A {};
anatofuz
parents:
diff changeset
388 template <typename T>
anatofuz
parents:
diff changeset
389 struct C : B<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
anatofuz
parents:
diff changeset
390 }
anatofuz
parents:
diff changeset
391
anatofuz
parents:
diff changeset
392 namespace type_in_second_dependent_base {
anatofuz
parents:
diff changeset
393 template <typename T>
anatofuz
parents:
diff changeset
394 struct A {};
anatofuz
parents:
diff changeset
395 template<typename T>
anatofuz
parents:
diff changeset
396 struct B { typedef T NameFromBase; };
anatofuz
parents:
diff changeset
397 template <typename T>
anatofuz
parents:
diff changeset
398 struct D : A<T>, B<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
anatofuz
parents:
diff changeset
399 }
anatofuz
parents:
diff changeset
400
anatofuz
parents:
diff changeset
401 namespace type_in_second_non_dependent_base {
anatofuz
parents:
diff changeset
402 struct A {};
anatofuz
parents:
diff changeset
403 struct B { typedef int NameFromBase; };
anatofuz
parents:
diff changeset
404 template<typename T>
anatofuz
parents:
diff changeset
405 struct C : A, B {};
anatofuz
parents:
diff changeset
406 template <typename T>
anatofuz
parents:
diff changeset
407 struct D : C<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
anatofuz
parents:
diff changeset
408 }
anatofuz
parents:
diff changeset
409
anatofuz
parents:
diff changeset
410 namespace type_in_virtual_base_of_dependent_base {
anatofuz
parents:
diff changeset
411 template <typename T>
anatofuz
parents:
diff changeset
412 struct A { typedef T NameFromBase; };
anatofuz
parents:
diff changeset
413 template <typename T>
anatofuz
parents:
diff changeset
414 struct B : virtual A<T> {};
anatofuz
parents:
diff changeset
415 template <typename T>
anatofuz
parents:
diff changeset
416 struct C : B<T>, virtual A<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
anatofuz
parents:
diff changeset
417 C<int> c;
anatofuz
parents:
diff changeset
418 }
anatofuz
parents:
diff changeset
419
anatofuz
parents:
diff changeset
420 namespace type_in_base_of_multiple_dependent_bases {
anatofuz
parents:
diff changeset
421 template <typename T>
anatofuz
parents:
diff changeset
422 struct A { typedef T NameFromBase; };
anatofuz
parents:
diff changeset
423 template <typename T>
anatofuz
parents:
diff changeset
424 struct B : public A<T> {};
anatofuz
parents:
diff changeset
425 template <typename T>
anatofuz
parents:
diff changeset
426 struct C : B<T>, public A<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-warning {{direct base 'A<int>' is inaccessible due to ambiguity:}}
anatofuz
parents:
diff changeset
427 C<int> c; // expected-note {{in instantiation of template class 'type_in_base_of_multiple_dependent_bases::C<int>' requested here}}
anatofuz
parents:
diff changeset
428 }
anatofuz
parents:
diff changeset
429
anatofuz
parents:
diff changeset
430 namespace type_in_dependent_base_of_non_dependent_type {
anatofuz
parents:
diff changeset
431 template<typename T> struct A { typedef int NameFromBase; };
anatofuz
parents:
diff changeset
432 template<typename T> struct B : A<T> {
anatofuz
parents:
diff changeset
433 struct C;
anatofuz
parents:
diff changeset
434 template<typename TT>
anatofuz
parents:
diff changeset
435 struct D : C {
anatofuz
parents:
diff changeset
436 NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
anatofuz
parents:
diff changeset
437 };
anatofuz
parents:
diff changeset
438 struct E : C {
anatofuz
parents:
diff changeset
439 NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
anatofuz
parents:
diff changeset
440 };
anatofuz
parents:
diff changeset
441 };
anatofuz
parents:
diff changeset
442 template<typename T> struct B<T>::C : B {
anatofuz
parents:
diff changeset
443 NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
anatofuz
parents:
diff changeset
444 };
anatofuz
parents:
diff changeset
445 template<typename T> struct F : B<T>::C {
anatofuz
parents:
diff changeset
446 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
anatofuz
parents:
diff changeset
447 };
anatofuz
parents:
diff changeset
448 }
anatofuz
parents:
diff changeset
449
anatofuz
parents:
diff changeset
450 namespace lookup_in_function_contexts {
anatofuz
parents:
diff changeset
451 template <typename T> struct A { typedef T NameFromBase; };
anatofuz
parents:
diff changeset
452 template <typename T>
anatofuz
parents:
diff changeset
453 struct B : A<T> {
anatofuz
parents:
diff changeset
454 // expected-warning@+1 {{lookup into dependent bases}}
anatofuz
parents:
diff changeset
455 static auto lateSpecifiedFunc() -> decltype(NameFromBase()) {
anatofuz
parents:
diff changeset
456 return {};
anatofuz
parents:
diff changeset
457 }
anatofuz
parents:
diff changeset
458
anatofuz
parents:
diff changeset
459 static void memberFunc() {
anatofuz
parents:
diff changeset
460 NameFromBase x; // expected-warning {{lookup into dependent bases}}
anatofuz
parents:
diff changeset
461 }
anatofuz
parents:
diff changeset
462
anatofuz
parents:
diff changeset
463 static void funcLocalClass() {
anatofuz
parents:
diff changeset
464 struct X {
anatofuz
parents:
diff changeset
465 NameFromBase x; // expected-warning {{lookup into dependent bases}}
anatofuz
parents:
diff changeset
466 } y;
anatofuz
parents:
diff changeset
467 }
anatofuz
parents:
diff changeset
468
anatofuz
parents:
diff changeset
469 void localClassMethod() {
anatofuz
parents:
diff changeset
470 struct X {
anatofuz
parents:
diff changeset
471 void bar() {
anatofuz
parents:
diff changeset
472 NameFromBase m; // expected-warning {{lookup into dependent bases}}
anatofuz
parents:
diff changeset
473 }
anatofuz
parents:
diff changeset
474 } x;
anatofuz
parents:
diff changeset
475 x.bar();
anatofuz
parents:
diff changeset
476 }
anatofuz
parents:
diff changeset
477
anatofuz
parents:
diff changeset
478 static void funcLambda() {
anatofuz
parents:
diff changeset
479 auto l = []() {
anatofuz
parents:
diff changeset
480 NameFromBase x; // expected-warning {{lookup into dependent bases}}
anatofuz
parents:
diff changeset
481 };
anatofuz
parents:
diff changeset
482 l();
anatofuz
parents:
diff changeset
483 }
anatofuz
parents:
diff changeset
484
anatofuz
parents:
diff changeset
485 static constexpr int constexprFunc() {
anatofuz
parents:
diff changeset
486 NameFromBase x = {}; // expected-warning {{lookup into dependent bases}}
anatofuz
parents:
diff changeset
487 return sizeof(x);
anatofuz
parents:
diff changeset
488 }
anatofuz
parents:
diff changeset
489
anatofuz
parents:
diff changeset
490 static auto autoFunc() {
anatofuz
parents:
diff changeset
491 NameFromBase x; // expected-warning {{lookup into dependent bases}}
anatofuz
parents:
diff changeset
492 return x;
anatofuz
parents:
diff changeset
493 }
anatofuz
parents:
diff changeset
494 };
anatofuz
parents:
diff changeset
495
anatofuz
parents:
diff changeset
496 // Force us to parse the methods.
anatofuz
parents:
diff changeset
497 template struct B<int>;
anatofuz
parents:
diff changeset
498 }
anatofuz
parents:
diff changeset
499
anatofuz
parents:
diff changeset
500 namespace function_template_deduction {
anatofuz
parents:
diff changeset
501 // Overloaded function templates.
anatofuz
parents:
diff changeset
502 template <int N> int f() { return N; }
anatofuz
parents:
diff changeset
503 template <typename T> int f() { return sizeof(T); }
anatofuz
parents:
diff changeset
504
anatofuz
parents:
diff changeset
505 // Dependent base class with type.
anatofuz
parents:
diff changeset
506 template <typename T>
anatofuz
parents:
diff changeset
507 struct A { typedef T NameFromBase; };
anatofuz
parents:
diff changeset
508 template <typename T>
anatofuz
parents:
diff changeset
509 struct B : A<T> {
anatofuz
parents:
diff changeset
510 // expected-warning@+1 {{found via unqualified lookup into dependent bases}}
anatofuz
parents:
diff changeset
511 int x = f<NameFromBase>();
anatofuz
parents:
diff changeset
512 };
anatofuz
parents:
diff changeset
513
anatofuz
parents:
diff changeset
514 // Dependent base class with enum.
anatofuz
parents:
diff changeset
515 template <typename T> struct C { enum { NameFromBase = 4 }; };
anatofuz
parents:
diff changeset
516 template <typename T> struct D : C<T> {
anatofuz
parents:
diff changeset
517 // expected-warning@+1 {{use of undeclared identifier 'NameFromBase'; unqualified lookup into dependent bases}}
anatofuz
parents:
diff changeset
518 int x = f<NameFromBase>();
anatofuz
parents:
diff changeset
519 };
anatofuz
parents:
diff changeset
520 }
anatofuz
parents:
diff changeset
521
anatofuz
parents:
diff changeset
522 namespace function_template_undef_impl {
anatofuz
parents:
diff changeset
523 template<class T>
anatofuz
parents:
diff changeset
524 void f() {
anatofuz
parents:
diff changeset
525 Undef::staticMethod(); // expected-error {{use of undeclared identifier 'Undef'}}
anatofuz
parents:
diff changeset
526 UndefVar.method(); // expected-error {{use of undeclared identifier 'UndefVar'}}
anatofuz
parents:
diff changeset
527 }
anatofuz
parents:
diff changeset
528 }
anatofuz
parents:
diff changeset
529
anatofuz
parents:
diff changeset
530 namespace PR20716 {
anatofuz
parents:
diff changeset
531 template <template <typename T> class A>
anatofuz
parents:
diff changeset
532 struct B : A<int>
anatofuz
parents:
diff changeset
533 {
anatofuz
parents:
diff changeset
534 XXX x; // expected-error {{unknown type name}}
anatofuz
parents:
diff changeset
535 };
anatofuz
parents:
diff changeset
536
anatofuz
parents:
diff changeset
537 template <typename T>
anatofuz
parents:
diff changeset
538 struct C {};
anatofuz
parents:
diff changeset
539
anatofuz
parents:
diff changeset
540 template <typename T>
anatofuz
parents:
diff changeset
541 using D = C<T>;
anatofuz
parents:
diff changeset
542
anatofuz
parents:
diff changeset
543 template <typename T>
anatofuz
parents:
diff changeset
544 struct E : D<T>
anatofuz
parents:
diff changeset
545 {
anatofuz
parents:
diff changeset
546 XXX x; // expected-error {{unknown type name}}
anatofuz
parents:
diff changeset
547 };
anatofuz
parents:
diff changeset
548 }
anatofuz
parents:
diff changeset
549
anatofuz
parents:
diff changeset
550 namespace PR23810 {
anatofuz
parents:
diff changeset
551 void f(int);
anatofuz
parents:
diff changeset
552 struct Base {
anatofuz
parents:
diff changeset
553 void f(); // expected-note{{must qualify identifier to find this declaration in dependent base class}}
anatofuz
parents:
diff changeset
554 };
anatofuz
parents:
diff changeset
555 template <typename T> struct Template : T {
anatofuz
parents:
diff changeset
556 void member() {
anatofuz
parents:
diff changeset
557 f(); // expected-warning {{found via unqualified lookup into dependent bases}}
anatofuz
parents:
diff changeset
558 }
anatofuz
parents:
diff changeset
559 };
anatofuz
parents:
diff changeset
560 void test() {
anatofuz
parents:
diff changeset
561 Template<Base> x;
anatofuz
parents:
diff changeset
562 x.member(); // expected-note{{requested here}}
anatofuz
parents:
diff changeset
563 };
anatofuz
parents:
diff changeset
564 }
anatofuz
parents:
diff changeset
565
anatofuz
parents:
diff changeset
566 namespace PR23823 {
anatofuz
parents:
diff changeset
567 // Don't delay lookup in SFINAE context.
anatofuz
parents:
diff changeset
568 template <typename T> decltype(g(T())) check(); // expected-note{{candidate template ignored: substitution failure [with T = int]: use of undeclared identifier 'g'}}
anatofuz
parents:
diff changeset
569 decltype(check<int>()) x; // expected-error{{no matching function for call to 'check'}}
anatofuz
parents:
diff changeset
570
anatofuz
parents:
diff changeset
571 void h();
anatofuz
parents:
diff changeset
572 template <typename T> decltype(h(T())) check2(); // expected-note{{candidate template ignored: substitution failure [with T = int]: no matching function for call to 'h'}}
anatofuz
parents:
diff changeset
573 decltype(check2<int>()) y; // expected-error{{no matching function for call to 'check2'}}
anatofuz
parents:
diff changeset
574 }
anatofuz
parents:
diff changeset
575
anatofuz
parents:
diff changeset
576 // We also allow unqualified lookup into bases in contexts where the we know the
anatofuz
parents:
diff changeset
577 // undeclared identifier *must* be a type, such as a new expression or catch
anatofuz
parents:
diff changeset
578 // parameter type.
anatofuz
parents:
diff changeset
579 template <typename T>
anatofuz
parents:
diff changeset
580 struct UseUnqualifiedTypeNames : T {
anatofuz
parents:
diff changeset
581 void foo() {
anatofuz
parents:
diff changeset
582 void *P = new TheType; // expected-warning {{unqualified lookup}} expected-error {{no type}}
anatofuz
parents:
diff changeset
583 size_t x = __builtin_offsetof(TheType, f2); // expected-warning {{unqualified lookup}} expected-error {{no type}}
anatofuz
parents:
diff changeset
584 try {
anatofuz
parents:
diff changeset
585 } catch (TheType) { // expected-warning {{unqualified lookup}} expected-error {{no type}}
anatofuz
parents:
diff changeset
586 }
anatofuz
parents:
diff changeset
587 enum E : IntegerType { E0 = 42 }; // expected-warning {{unqualified lookup}} expected-error {{no type}}
anatofuz
parents:
diff changeset
588 _Atomic(TheType) a; // expected-warning {{unqualified lookup}} expected-error {{no type}}
anatofuz
parents:
diff changeset
589 }
anatofuz
parents:
diff changeset
590 void out_of_line();
anatofuz
parents:
diff changeset
591 };
anatofuz
parents:
diff changeset
592 template <typename T>
anatofuz
parents:
diff changeset
593 void UseUnqualifiedTypeNames<T>::out_of_line() {
anatofuz
parents:
diff changeset
594 void *p = new TheType; // expected-warning {{unqualified lookup}} expected-error {{no type}}
anatofuz
parents:
diff changeset
595 }
anatofuz
parents:
diff changeset
596 struct Base {
anatofuz
parents:
diff changeset
597 typedef int IntegerType;
anatofuz
parents:
diff changeset
598 struct TheType {
anatofuz
parents:
diff changeset
599 int f1, f2;
anatofuz
parents:
diff changeset
600 };
anatofuz
parents:
diff changeset
601 };
anatofuz
parents:
diff changeset
602 template struct UseUnqualifiedTypeNames<Base>;
anatofuz
parents:
diff changeset
603 struct BadBase { };
anatofuz
parents:
diff changeset
604 template struct UseUnqualifiedTypeNames<BadBase>; // expected-note-re 2 {{in instantiation {{.*}} requested here}}
anatofuz
parents:
diff changeset
605
anatofuz
parents:
diff changeset
606 namespace partial_template_lookup {
anatofuz
parents:
diff changeset
607
anatofuz
parents:
diff changeset
608 class Bar;
anatofuz
parents:
diff changeset
609 class Spare;
anatofuz
parents:
diff changeset
610
anatofuz
parents:
diff changeset
611 template <class T, class X = Bar>
anatofuz
parents:
diff changeset
612 class FooTemplated;
anatofuz
parents:
diff changeset
613
anatofuz
parents:
diff changeset
614 class FooBase {
anatofuz
parents:
diff changeset
615 public:
anatofuz
parents:
diff changeset
616 typedef int BaseTypedef;
anatofuz
parents:
diff changeset
617 };
anatofuz
parents:
diff changeset
618
anatofuz
parents:
diff changeset
619 // Partial template spec (unused)
anatofuz
parents:
diff changeset
620 template <class T>
anatofuz
parents:
diff changeset
621 class FooTemplated<T, Spare> {};
anatofuz
parents:
diff changeset
622
anatofuz
parents:
diff changeset
623 // Partial template spec (used)
anatofuz
parents:
diff changeset
624 template <class T>
anatofuz
parents:
diff changeset
625 class FooTemplated<T, Bar> : public FooBase {};
anatofuz
parents:
diff changeset
626
anatofuz
parents:
diff changeset
627 // Full template spec
anatofuz
parents:
diff changeset
628 template <class T, class X>
anatofuz
parents:
diff changeset
629 class FooTemplated : public FooTemplated<T, Bar> {
anatofuz
parents:
diff changeset
630 public:
anatofuz
parents:
diff changeset
631 BaseTypedef Member; // expected-warning {{unqualified lookup}}
anatofuz
parents:
diff changeset
632 };
anatofuz
parents:
diff changeset
633 }