[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaCXX / cxx20-ctad-type-alias.cpp
blob2d43e46b9e3d76bf7d6b5a1bd0e82b75f50dcec6
1 // RUN: %clang_cc1 -fsyntax-only -triple x86_64-unknown-linux -Wno-c++11-narrowing -Wno-literal-conversion -std=c++20 -verify %s
3 namespace test1 {
4 template <typename T>
5 struct Foo { T t; };
6 template <typename U>
7 using Bar = Foo<U>;
9 Bar s = {1};
10 } // namespace test1
12 namespace test2 {
13 template <typename X, typename Y>
14 struct XYpair {
15 X x;
16 Y y;
18 // A tricky explicit deduction guide that swapping X and Y.
19 template <typename X, typename Y>
20 XYpair(X, Y) -> XYpair<Y, X>;
21 template <typename U, typename V>
22 using AliasXYpair = XYpair<U, V>;
24 AliasXYpair xy = {1.1, 2}; // XYpair<int, double>
25 static_assert(__is_same(decltype(xy.x), int));
26 static_assert(__is_same(decltype(xy.y), double));
27 } // namespace test2
29 namespace test3 {
30 template <typename T, class>
31 struct container {
32 // test with default arguments.
33 container(T a, T b = T());
36 template <class T>
37 using vector = container<T, int>;
38 vector v(0, 0);
39 } // namespace test3
41 namespace test4 {
42 // Explicit deduction guide.
43 template <class T>
44 struct X {
45 T t;
46 X(T);
49 template <class T>
50 X(T) -> X<double>;
52 template <class T>
53 using AX = X<T>;
55 AX s = {1};
56 static_assert(__is_same(decltype(s.t), double)); // explicit one is picked.
57 } // namespace test4
59 namespace test5 {
60 template <int B>
61 struct Foo {};
62 // Template parameter pack
63 template <int... C>
64 using AF = Foo<1>;
65 auto a = AF{};
66 } // namespace test5
68 namespace test6 {
69 // non-type template argument.
70 template <typename T, bool B = false>
71 struct Foo {
72 Foo(T);
74 template <typename T>
75 using AF = Foo<T, 1>;
77 AF b{0};
78 } // namespace test6
80 namespace test7 {
81 template <typename T>
82 struct Foo {
83 Foo(T);
85 // using alias chain.
86 template <typename U>
87 using AF1 = Foo<U>;
88 template <typename K>
89 using AF2 = AF1<K>;
90 AF2 b = 1;
91 } // namespace test7
93 namespace test8 {
94 template <typename T, int N>
95 struct Foo {
96 Foo(T const (&)[N]);
99 template <typename X, int Y>
100 using Bar = Foo<X, Y>;
102 Bar s = {{1}};
103 } // namespace test8
105 namespace test9 {
106 template <typename T, int N>
107 struct Foo {
108 Foo(T const (&)[N]);
111 template <typename X, int Y>
112 using Bar = Foo<X, sizeof(X)>; // expected-note {{candidate template ignored: couldn't infer template argument 'X'}} \
113 // expected-note {{implicit deduction guide declared as 'template <typename X> requires __is_deducible(test9::Bar, Foo<X, sizeof(X)>) Bar(Foo<X, sizeof(X)>) -> Foo<X, sizeof(X)>'}} \
114 // expected-note {{implicit deduction guide declared as 'template <typename X> requires __is_deducible(test9::Bar, Foo<X, sizeof(X)>) Bar(const X (&)[sizeof(X)]) -> Foo<X, sizeof(X)>'}} \
115 // expected-note {{candidate template ignored: constraints not satisfied [with X = int]}} \
116 // expected-note {{cannot deduce template arguments for 'Bar' from 'Foo<int, 4UL>'}}
119 Bar s = {{1}}; // expected-error {{no viable constructor or deduction guide }}
120 } // namespace test9
122 namespace test10 {
123 template <typename T>
124 struct Foo {
125 template <typename U>
126 Foo(U);
129 template <typename U>
130 Foo(U) -> Foo<U*>;
132 template <typename K>
133 using A = Foo<K>;
134 A a(2); // Foo<int*>
135 } // namespace test10
137 namespace test11 {
138 struct A {};
139 template<class T> struct Foo { T c; };
140 template<class X, class Y=A>
141 using AFoo = Foo<Y>; // expected-note {{candidate template ignored: could not match 'Foo<Y>' against 'int'}} \
142 // expected-note {{implicit deduction guide declared as 'template <class Y = A> requires __is_deducible(test11::AFoo, Foo<Y>) AFoo(Foo<Y>) -> Foo<Y>'}} \
143 // expected-note {{candidate template ignored: constraints not satisfied [with Y = int]}} \
144 // expected-note {{cannot deduce template arguments for 'AFoo' from 'Foo<int>'}} \
145 // expected-note {{implicit deduction guide declared as 'template <class Y = A> requires __is_deducible(test11::AFoo, Foo<Y>) AFoo(Y) -> Foo<Y>'}} \
146 // expected-note {{candidate function template not viable: requires 0 arguments, but 1 was provided}} \
147 // expected-note {{implicit deduction guide declared as 'template <class Y = A> requires __is_deducible(test11::AFoo, Foo<Y>) AFoo() -> Foo<Y>'}}
149 AFoo s = {1}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'AFoo'}}
150 } // namespace test11
152 namespace test12 {
153 // no crash on null access attribute
154 template<typename X>
155 struct Foo {
156 template<typename K>
157 struct Bar {
158 Bar(K);
161 template<typename U>
162 using ABar = Bar<U>;
163 void test() { ABar k = 2; }
166 void func(Foo<int> s) {
167 s.test();
169 } // namespace test12
171 namespace test13 {
172 template <typename... Ts>
173 struct Foo {
174 Foo(Ts...);
177 template <typename... Ts>
178 using AFoo = Foo<Ts...>;
180 auto b = AFoo{};
181 AFoo a(1, 2);
183 template <typename T>
184 using BFoo = Foo<T, T>;
185 BFoo b2(1.0, 2.0);
186 } // namespace test13
188 namespace test14 {
189 template<typename T>
190 concept IsInt = __is_same(decltype(T()), int);
192 template<IsInt T, int N>
193 struct Foo {
194 Foo(T const (&)[N]);
197 template <int K>
198 using Bar = Foo<double, K>; // expected-note {{constraints not satisfied for class template 'Foo'}}
199 // expected-note@-1 {{candidate template ignored: could not match}}
200 // expected-note@-2 {{implicit deduction guide declared as 'template <int K> requires __is_deducible(test14::Bar, Foo<double, K>) Bar(Foo<double, K>) -> Foo<double, K>'}}
201 // expected-note@-3 {{implicit deduction guide declared as 'template <int K> requires __is_deducible(test14::Bar, Foo<double, K>) Bar(const double (&)[K]) -> Foo<double, K>'}}
202 double abc[3];
203 Bar s2 = {abc}; // expected-error {{no viable constructor or deduction guide for deduction }}
204 } // namespace test14
206 namespace test15 {
207 template <class T> struct Foo { Foo(T); };
209 template<class V> using AFoo = Foo<V *>;
210 template<typename> concept False = false;
211 template<False W>
212 using BFoo = AFoo<W>; // expected-note {{candidate template ignored: constraints not satisfied [with V = int]}} \
213 // expected-note {{cannot deduce template arguments for 'BFoo' from 'Foo<int *>'}} \
214 // expected-note {{implicit deduction guide declared as 'template <class V> requires __is_deducible(AFoo, Foo<V *>) && __is_deducible(test15::BFoo, Foo<V *>) BFoo(V *) -> Foo<V *>}} \
215 // expected-note {{candidate template ignored: could not match 'Foo<V *>' against 'int *'}} \
216 // expected-note {{template <class V> requires __is_deducible(AFoo, Foo<V *>) && __is_deducible(test15::BFoo, Foo<V *>) BFoo(Foo<V *>) -> Foo<V *>}}
217 int i = 0;
218 AFoo a1(&i); // OK, deduce Foo<int *>
220 // the W is not deduced from the deduced type Foo<int *>.
221 BFoo b2(&i); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'BFoo'}}
222 } // namespace test15
224 namespace test16 {
225 struct X { X(int); X(const X&); };
226 template<class T>
227 struct Foo {
228 T t;
229 Foo(T t) : t(t) {}
231 template<class T>
232 using AFoo = Foo<T>;
233 int i = 0;
234 AFoo s{i};
235 static_assert(__is_same(decltype(s.t), int));
237 // explicit deduction guide.
238 Foo(int) -> Foo<X>;
239 AFoo s2{i};
240 // FIXME: the type should be X because of the above explicit deduction guide.
241 static_assert(__is_same(decltype(s2.t), int));
242 } // namespace test16
244 namespace test17 {
245 template <typename T>
246 struct Foo { T t; };
248 // CTAD for alias templates only works for the RHS of the alias of form of
249 // [typename] [nested-name-specifier] [template] simple-template-id
250 template <typename U>
251 using AFoo = Foo<U>*; // expected-note {{template is declared here}}
253 AFoo s = {1}; // expected-error {{alias template 'AFoo' requires template arguments; argument deduction only allowed for}}
254 } // namespace test17
256 namespace test18 {
257 template<typename T>
258 concept False = false; // expected-note {{because 'false' evaluated to false}}
260 template <typename T> struct Foo { T t; };
262 template<typename T> requires False<T> // expected-note {{because 'int' does not satisfy 'False'}}
263 Foo(T) -> Foo<int>;
265 template <typename U>
266 using Bar = Foo<U>; // expected-note {{could not match 'Foo<U>' against 'int'}} \
267 // expected-note {{implicit deduction guide declared as 'template <typename U> requires __is_deducible(test18::Bar, Foo<U>) Bar(Foo<U>) -> Foo<U>'}} \
268 // expected-note {{candidate template ignored: constraints not satisfied}} \
269 // expected-note {{implicit deduction guide declared as 'template <typename T> requires False<T> && __is_deducible(test18::Bar, Foo<int>) Bar(T) -> Foo<int>'}} \
270 // expected-note {{candidate function template not viable}} \
271 // expected-note {{implicit deduction guide declared as 'template <typename U> requires __is_deducible(test18::Bar, Foo<U>) Bar() -> Foo<U>'}}
273 Bar s = {1}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments}}
274 } // namespace test18
276 // GH85406, verify no crash on invalid alias templates.
277 namespace test19 {
278 template <typename T>
279 class Foo {};
281 template <typename T>
282 template <typename K>
283 using Bar2 = Foo<K>; // expected-error {{extraneous template parameter list in alias template declaration}}
285 Bar2 b = 1; // expected-error {{no viable constructor or deduction guide for deduction of template arguments}}
286 } // namespace test19
288 // GH85385
289 namespace test20 {
290 template <template <typename> typename T>
291 struct K {};
293 template <typename U>
294 class Foo {};
296 // Verify that template template type parameter TTP is referenced/used in the
297 // template arguments of the RHS.
298 template <template<typename> typename TTP>
299 using Bar = Foo<K<TTP>>; // expected-note {{candidate template ignored: could not match 'Foo<K<TTP>>' against 'int'}} \
300 // expected-note {{implicit deduction guide declared as 'template <template <typename> typename TTP> requires __is_deducible(test20::Bar, Foo<K<TTP>>) Bar(Foo<K<TTP>>) -> Foo<K<TTP>>'}}
302 template <class T>
303 class Container {};
304 Bar t = Foo<K<Container>>();
306 Bar s = 1; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of}}
307 } // namespace test20
309 namespace test21 {
310 template <typename T, unsigned N>
311 struct Array { const T member[N]; };
312 template <unsigned N>
313 using String = Array<char, N>;
315 // Verify no crash on constructing the aggregate deduction guides.
316 String s("hello");
317 } // namespace test21
319 // GH89013
320 namespace test22 {
321 class Base {};
322 template <typename T>
323 class Derived final : public Base {};
325 template <typename T, typename D>
326 requires __is_base_of(Base, D)
327 struct Foo {
328 explicit Foo(D) {}
331 template <typename U>
332 using AFoo = Foo<int, Derived<U>>;
334 AFoo a(Derived<int>{});
335 } // namespace test22
337 namespace test23 {
338 // We have an aggregate deduction guide "G(T) -> G<T>".
339 template<typename T>
340 struct G { T t1; };
342 template<typename X = int>
343 using AG = G<int>;
345 AG ag(1.0);
346 // Verify that the aggregate deduction guide "AG(int) -> AG<int>" is built and
347 // choosen.
348 static_assert(__is_same(decltype(ag.t1), int));
349 } // namespace test23
351 // GH90177
352 // verify that the transformed require-clause of the alias deduction gudie has
353 // the right depth info.
354 namespace test24 {
355 class Forward;
356 class Key {};
358 template <typename D>
359 constexpr bool C = sizeof(D);
361 // Case1: the alias template and the underlying deduction guide are in the same
362 // scope.
363 template <typename T>
364 struct Case1 {
365 template <typename U>
366 struct Foo {
367 Foo(U);
370 template <typename V>
371 requires (C<V>)
372 Foo(V) -> Foo<V>;
374 template <typename Y>
375 using Alias = Foo<Y>;
377 // The require-clause should be evaluated on the type Key.
378 Case1<Forward>::Alias t2 = Key();
381 // Case2: the alias template and underlying deduction guide are in different
382 // scope.
383 template <typename T>
384 struct Foo {
385 Foo(T);
387 template <typename U>
388 requires (C<U>)
389 Foo(U) -> Foo<U>;
391 template <typename T>
392 struct Case2 {
393 template <typename Y>
394 using Alias = Foo<Y>;
396 // The require-caluse should be evaluated on the type Key.
397 Case2<Forward>::Alias t1 = Key();
399 // Case3: crashes on the constexpr evaluator due to the mixed-up depth in
400 // require-expr.
401 template <class T1>
402 struct A1 {
403 template<class T2>
404 struct A2 {
405 template <class T3>
406 struct Foo {
407 Foo(T3);
409 template <class T3>
410 requires C<T3>
411 Foo(T3) -> Foo<T3>;
414 template <typename U>
415 using AFoo = A1<int>::A2<int>::Foo<U>;
416 AFoo case3(1);
418 // Case4: crashes on the constexpr evaluator due to the mixed-up index for the
419 // template parameters `V`.
420 template<class T, typename T2>
421 struct Case4 {
422 template<class V> requires C<V>
423 Case4(V, T);
426 template<class T2>
427 using ACase4 = Case4<T2, T2>;
428 ACase4 case4{0, 1};
430 } // namespace test24
432 namespace GH92212 {
433 template<typename T, typename...Us>
434 struct A{
435 template<typename V> requires __is_same(V, int)
436 A(V);
439 template<typename...TS>
440 using AA = A<int, TS...>;
441 AA a{0};
444 namespace GH94927 {
445 template <typename T>
446 struct A {
447 A(T);
449 A(int) -> A<char>;
451 template <typename U>
452 using B1 = A<U>;
453 B1 b1(100); // deduce to A<char>;
454 static_assert(__is_same(decltype(b1), A<char>));
456 template <typename U>
457 requires (!__is_same(U, char)) // filter out the explicit deduction guide.
458 using B2 = A<U>;
459 template <typename V>
460 using B3 = B2<V>;
462 B2 b2(100); // deduced to A<int>;
463 static_assert(__is_same(decltype(b2), A<int>));
464 B3 b3(100); // decuded to A<int>;
465 static_assert(__is_same(decltype(b3), A<int>));
468 // the nested case
469 template <typename T1>
470 struct Out {
471 template <typename T2>
472 struct A {
473 A(T2);
475 A(int) -> A<T1>;
477 template <typename T3>
478 using B = A<T3>;
481 Out<float>::B out(100); // deduced to Out<float>::A<float>;
482 static_assert(__is_same(decltype(out), Out<float>::A<float>));
485 namespace GH111508 {
487 template <typename V> struct S {
488 using T = V;
489 T Data;
492 template <typename V> using Alias = S<V>;
494 Alias A(42);
496 } // namespace GH111508
498 namespace GH113518 {
500 template <class T, unsigned N> struct array {
501 T value[N];
504 template <typename Tp, typename... Up>
505 array(Tp, Up...) -> array<Tp, 1 + sizeof...(Up)>;
507 template <typename T> struct ArrayType {
508 template <unsigned size> using Array = array<T, size>;
511 template <ArrayType<int>::Array array> void test() {}
513 void foo() { test<{1, 2, 3}>(); }
515 } // namespace GH113518