xref: /llvm-project/clang/test/SemaTemplate/instantiate-local-class.cpp (revision 862715ea813d8ffa73050ada17567b45c41a1023)
1 // RUN: %clang_cc1 -verify -std=c++11 %s
2 // RUN: %clang_cc1 -verify -std=c++11 -fdelayed-template-parsing %s
3 // RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
4 
5 template<typename T>
6 void f0() {
7   struct X;
8   typedef struct Y {
9     T (X::* f1())(int) { return 0; }
10   } Y2;
11 
12   Y2 y = Y();
13 }
14 
15 template void f0<int>();
16 
17 // PR5764
18 namespace PR5764 {
19   struct X {
20     template <typename T>
21     void Bar() {
22       typedef T ValueType;
23       struct Y {
24         Y() { V = ValueType(); }
25 
26         ValueType V;
27       };
28 
29       Y y;
30     }
31   };
32 
33   void test(X x) {
34     x.Bar<int>();
35   }
36 }
37 
38 // Instantiation of local classes with virtual functions.
39 namespace local_class_with_virtual_functions {
40   template <typename T> struct X { };
41   template <typename T> struct Y { };
42 
43   template <typename T>
44   void f() {
45     struct Z : public X<Y<T>*> {
46       virtual void g(Y<T>* y) { }
47       void g2(int x) {(void)x;}
48     };
49     Z z;
50     (void)z;
51   }
52 
53   struct S { };
54   void test() { f<S>(); }
55 }
56 
57 namespace PR8801 {
58   template<typename T>
59   void foo() {
60     class X;
61     typedef int (X::*pmf_type)();
62     class X : public T { };
63 
64     pmf_type pmf = &T::foo;
65   }
66 
67   struct Y { int foo(); };
68 
69   template void foo<Y>();
70 }
71 
72 namespace TemplatePacksAndLambdas {
73   template <typename ...T> int g(T...);
74   struct S {
75     template <typename ...T> static void f(int f = g([]{ static T t; return ++t; }()...)) {}
76   };
77   void h() { S::f<int, int, int>(); }
78 }
79 
80 namespace PR9685 {
81   template <class Thing> void forEach(Thing t) { t.func(); }
82 
83   template <typename T> void doIt() {
84     struct Functor {
85       void func() { (void)i; }
86       int i;
87     };
88 
89     forEach(Functor());
90   }
91 
92   void call() {
93     doIt<int>();
94   }
95 }
96 
97 namespace PR12702 {
98   struct S {
99     template <typename F> bool apply(F f) { return f(); }
100   };
101 
102   template <typename> struct T {
103     void foo() {
104       struct F {
105         int x;
106 
107         bool operator()() { return x == 0; }
108       };
109 
110       S().apply(F());
111     }
112   };
113 
114   void call() { T<int>().foo(); }
115 }
116 
117 namespace PR17139 {
118   template <class T> void foo(const T &t) { t.foo(); }
119 
120   template <class F> void bar(F *f) {
121     struct B {
122       F *fn;
123       void foo() const { fn(); }
124     } b = { f };
125     foo(b);
126   }
127 
128   void go() {}
129 
130   void test() { bar(go); }
131 }
132 
133 namespace PR17740 {
134 class C {
135 public:
136   template <typename T> static void foo(T function);
137   template <typename T> static void bar(T function);
138   template <typename T> static void func(T function);
139 };
140 
141 template <typename T> void C::foo(T function) { function(); }
142 
143 template <typename T> void C::bar(T function) {
144   foo([&function]() { function(); });
145 }
146 
147 template <typename T> void C::func(T function) {
148   struct Struct {
149     T mFunction;
150 
151     Struct(T function) : mFunction(function) {};
152 
153     void operator()() {
154       mFunction();
155     };
156   };
157 
158   bar(Struct(function));
159 }
160 
161 void call() {
162   C::func([]() {});
163 }
164 }
165 
166 namespace PR14373 {
167   struct function {
168     template <typename _Functor> function(_Functor __f) { __f(); }
169   };
170   template <typename Func> function exec_func(Func f) {
171     struct functor {
172       functor(Func f) : func(f) {}
173       void operator()() const { func(); }
174       Func func;
175     };
176     return functor(f);
177   }
178   struct Type {
179     void operator()() const {}
180   };
181   int call() {
182     exec_func(Type());
183     return 0;
184   }
185 }
186 
187 namespace PR18907 {
188 template <typename>
189 class C : public C<int> {}; // expected-error{{within its own definition}}
190 
191 template <typename X>
192 void F() {
193   struct A : C<X> {};
194 }
195 
196 struct B {
197   void f() { F<int>(); }
198 };
199 }
200 
201 namespace PR23194 {
202   struct X {
203     int operator()() const { return 0; }
204   };
205   struct Y {
206     Y(int) {}
207   };
208   template <bool = true> int make_seed_pair() noexcept {
209     struct state_t {
210       X x;
211       Y y{x()};
212     };
213     return 0;
214   }
215   int func() {
216     return make_seed_pair();
217   }
218 }
219 
220 namespace PR18653 {
221   // Forward declarations
222 
223   template<typename T> void f1() {
224     void g1(struct x1);
225     struct x1 {};
226   }
227   template void f1<int>();
228 
229   template<typename T> void f1a() {
230     void g1(union x1);
231     union x1 {};
232   }
233   template void f1a<int>();
234 
235   template<typename T> void f2() {
236     void g2(enum x2);  // expected-error{{ISO C++ forbids forward references to 'enum' types}}
237     enum x2 { nothing };
238   }
239   template void f2<int>();
240 
241   template<typename T> void f3() {
242     enum class x3;
243     void g3(enum x3);
244     enum class x3 { nothing };
245   }
246   template void f3<int>();
247 
248 
249   template<typename T> void f4() {
250     void g4(struct x4 {} x);  // expected-error{{'x4' cannot be defined in a parameter type}}
251   }
252   template void f4<int>();
253 
254   template<typename T> void f4a() {
255     void g4(union x4 {} x);  // expected-error{{'x4' cannot be defined in a parameter type}}
256   }
257   template void f4a<int>();
258 
259 
260   template <class T> void f();
261   template <class T> struct S1 {
262     void m() {
263       f<class newclass>();
264       f<union newunion>();
265     }
266   };
267   template struct S1<int>;
268 
269   template <class T> struct S2 {
270     void m() {
271       f<enum new_enum>();  // expected-error{{ISO C++ forbids forward references to 'enum' types}}
272     }
273   };
274   template struct S2<int>;
275 
276   template <class T> struct S3 {
277     void m() {
278       enum class new_enum;
279       f<enum new_enum>();
280     }
281   };
282   template struct S3<int>;
283 
284   template <class T> struct S4 {
285     struct local {};
286     void m() {
287       f<local>();
288     }
289   };
290   template struct S4<int>;
291 
292   template <class T> struct S4a {
293     union local {};
294     void m() {
295       f<local>();
296     }
297   };
298   template struct S4a<int>;
299 
300   template <class T> struct S5 {
301     enum local { nothing };
302     void m() {
303       f<local>();
304     }
305   };
306   template struct S5<int>;
307 
308   template <class T> struct S7 {
309     enum class local { nothing };
310     void m() {
311       f<local>();
312     }
313   };
314   template struct S7<int>;
315 
316 
317   template <class T> void fff(T *x);
318   template <class T> struct S01 {
319     struct local { };
320     void m() {
321       local x;
322       fff(&x);
323     }
324   };
325   template struct S01<int>;
326 
327   template <class T> struct S01a {
328     union local { };
329     void m() {
330       local x;
331       fff(&x);
332     }
333   };
334   template struct S01a<int>;
335 
336   template <class T> struct S02 {
337     enum local { nothing };
338     void m() {
339       local x;
340       fff(&x);
341     }
342   };
343   template struct S02<int>;
344 
345   template <class T> struct S03 {
346     enum class local { nothing };
347     void m() {
348       local x;
349       fff(&x);
350     }
351   };
352   template struct S03<int>;
353 
354 
355   template <class T> struct S04 {
356     void m() {
357       struct { } x;
358       fff(&x);
359     }
360   };
361   template struct S04<int>;
362 
363   template <class T> struct S04a {
364     void m() {
365       union { } x;
366       fff(&x);
367     }
368   };
369   template struct S04a<int>;
370 
371   template <class T> struct S05 {
372     void m() {
373       enum { nothing } x;
374       fff(&x);
375     }
376   };
377   template struct S05<int>;
378 
379   template <class T> struct S06 {
380     void m() {
381       class { virtual void mmm() {} } x;
382       fff(&x);
383     }
384   };
385   template struct S06<int>;
386 }
387 
388 namespace PR20625 {
389 template <typename T>
390 void f() {
391   struct N {
392     static constexpr int get() { return 42; }
393   };
394   constexpr int n = N::get();
395   static_assert(n == 42, "n == 42");
396 }
397 
398 void g() { f<void>(); }
399 }
400 
401 
402 namespace PR21332 {
403   template<typename T> void f1() {
404     struct S {  // expected-note{{in instantiation of member class 'S' requested here}}
405       void g1(int n = T::error);  // expected-error{{type 'int' cannot be used prior to '::' because it has no members}} \
406                                   // expected-note {{in instantiation of default function argument expression for 'g1<int>' required here}}
407     };
408   }
409   template void f1<int>();  // expected-note{{in instantiation of function template specialization 'PR21332::f1<int>' requested here}}
410 
411   template<typename T> void f2() {
412     struct S {  // expected-note{{in instantiation of member class 'S' requested here}}
413       void g2() noexcept(T::error);  // expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
414     };
415   }
416   template void f2<int>();  // expected-note{{in instantiation of function template specialization 'PR21332::f2<int>' requested here}}
417 
418   template<typename T> void f3() {
419     enum S {
420       val = T::error;  // expected-error{{expected '}' or ','}} expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
421     };
422   }
423   template void f3<int>();  //expected-note{{in instantiation of function template specialization 'PR21332::f3<int>' requested here}}
424 
425   template<typename T> void f4() {
426     enum class S {
427       val = T::error;  // expected-error{{expected '}' or ','}} expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
428     };
429   }
430   template void f4<int>();  // expected-note{{in instantiation of function template specialization 'PR21332::f4<int>' requested here}}
431 
432   template<typename T> void f5() {
433     class S {  // expected-note {{in instantiation of default member initializer 'PR21332::f5()::S::val' requested here}}
434       int val = T::error;  // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
435      };
436   }
437   template void f5<int>();  // expected-note {{in instantiation of function template specialization 'PR21332::f5<int>' requested here}}
438 
439   template<typename T> void f6() {
440     class S {  // expected-note {{in instantiation of member function 'PR21332::f6()::S::get' requested here}}
441       void get() {
442         class S2 {  // expected-note {{in instantiation of member class 'S2' requested here}}
443           void g1(int n = T::error);  // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} \
444                                       // expected-note  {{in instantiation of default function argument expression for 'g1<int>' required here}}
445         };
446       }
447     };
448   }
449   template void f6<int>();  // expected-note{{in instantiation of function template specialization 'PR21332::f6<int>' requested here}}
450 
451   template<typename T> void f7() {
452     struct S { void g() noexcept(undefined_val); };  // expected-error{{use of undeclared identifier 'undefined_val'}}
453   }
454   template void f7<int>();
455 }
456 
457 // Ensure that we correctly perform implicit conversions when instantiating the
458 // default arguments of local functions.
459 namespace rdar23721638 {
460   struct A {
461     A(const char *) = delete;  // expected-note 2 {{explicitly marked deleted here}}
462   };
463 
464   template <typename T> void foo() {
465     struct Inner { // expected-note {{in instantiation}}
466       void operator()(T a = "") {} // expected-error {{conversion function from 'const char[1]' to 'rdar23721638::A' invokes a deleted function}} \
467                                    // expected-note  {{in instantiation of default function argument expression for 'operator()<rdar23721638::A>' required here}} \
468                                    // expected-note  {{passing argument to parameter 'a' here}}
469     };
470     Inner()();
471   }
472   template void foo<A>(); // expected-note {{in instantiation}}
473 
474   template <typename T> void bar() {
475     auto lambda = [](T a = "") {}; // expected-error {{conversion function from 'const char[1]' to 'rdar23721638::A' invokes a deleted function}} \
476                                    // expected-note  {{in instantiation of default function argument expression for 'operator()<rdar23721638::A>' required here}} \
477                                    // expected-note  {{passing argument to parameter 'a' here}}
478     lambda();
479   }
480   template void bar<A>(); // expected-note {{in instantiation}}
481 }
482 
483 namespace anon_union_default_member_init {
484   template<typename T> void f() {
485     struct S {
486       union {
487         int i = 0;
488       };
489     };
490   }
491   void g() { f<int>(); }
492 }
493 
494 namespace PR45000 {
495   template <typename T>
496   void f(int x = [](T x = nullptr) -> int { return x; }());
497   // expected-error@-1 {{cannot initialize a parameter of type 'int' with an rvalue of type 'std::nullptr_t'}}
498   // expected-note@-2  {{in instantiation of default function argument expression for 'operator()<int>' required here}}
499   // expected-note@-3  {{passing argument to parameter 'x' here}}
500 
501   void g() { f<int>(); }
502   // expected-note@-1 {{in instantiation of default function argument expression for 'f<int>' required here}}
503 }
504 
505 namespace LambdaInDefaultMemberInitializer {
506   template<typename T> void f() {
507     struct S {
508       void *p = [this] { return &p; }();
509     };
510   }
511   template void f<int>();
512 }
513 
514 #if __cplusplus >= 201703L
515 
516 // Reduced from https://github.com/llvm/llvm-project/issues/98526
517 // This relies on the deferral instantiation of the local lambda, otherwise we would fail in DeduceReturnType().
518 namespace local_recursive_lambda {
519 
520 template <typename F> struct recursive_lambda {
521   template <typename... Args> auto operator()(Args &&...args) const {
522     return fn(*this, args...);
523   }
524   F fn;
525 };
526 
527 template <typename F> recursive_lambda(F) -> recursive_lambda<F>;
528 
529 void foo() {
530   recursive_lambda{[&](auto &self_fn, int) -> int {
531     return self_fn(0);
532   }}(0);
533 }
534 
535 } // namespace local_recursive_lambda
536 
537 #endif
538