[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaTemplate / generic-lambda.cpp
blob804eeaa29d6a1dd9413a5ffdd0bc25376b24fac8
1 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
3 // expected-no-diagnostics
5 template <class T, class U> constexpr bool is_same_v = false;
6 template <class T> constexpr bool is_same_v<T, T> = true;
7 template <class T, class U>
8 concept is_same = is_same_v<T, U>;
10 template <class T> struct X {};
11 template <class T, class U>
12 concept C1 = is_same<T, X<U>>;
14 template <class T1> X<X<X<T1>>> t1() {
15 return []<class T2>(T2) -> X<X<T2>> {
16 struct S {
17 static X<X<T2>> f() {
18 return []<class T3>(T3) -> X<T3> {
19 static_assert(is_same<T2, X<T1>>);
20 static_assert(is_same<T3, X<T2>>);
21 return X<T3>();
22 }(X<T2>());
25 return S::f();
26 }(X<T1>());
28 template X<X<X<int>>> t1<int>();
30 #if 0 // FIXME: crashes
31 template<class T1> auto t2() {
32 return []<class T2>(T2) {
33 struct S {
34 static auto f() {
35 return []<class T3>(T3) {
36 static_assert(is_same<T2, X<T1>>);
37 static_assert(is_same<T3, X<T2>>);
38 return X<T3>();
39 }(X<T2>());
42 return S::f();
43 }(X<T1>());
45 template auto t2<int>();
46 static_assert(is_same<decltype(t2<int>()), X<X<X<int>>>>);
48 template<class T1> C1<X<X<T1>>> auto t3() {
49 return []<C1<T1> T2>(T2) -> C1<X<T2>> auto {
50 struct S {
51 static auto f() {
52 return []<C1<T2> T3>(T3) -> C1<T3> auto {
53 return X<T3>();
54 }(X<T2>());
57 return S::f();
58 }(X<T1>());
60 template C1<X<X<int>>> auto t3<int>();
61 static_assert(is_same<decltype(t3<int>()), X<X<X<int>>>>);
62 #endif
64 namespace GH95735 {
66 int g(int fn) {
67 return [f = fn](auto tpl) noexcept(noexcept(f)) { return f; }(0);
70 int foo(auto... fn) {
71 // FIXME: This one hits the assertion "if the exception specification is dependent,
72 // then the noexcept expression should be value-dependent" in the constructor of
73 // FunctionProtoType.
74 // One possible solution is to update Sema::canThrow() to consider expressions
75 // (e.g. DeclRefExpr/FunctionParmPackExpr) involving unexpanded parameters as Dependent.
76 // This would effectively add an extra value-dependent flag to the noexcept expression.
77 // However, I'm afraid that would also cause ABI breakage.
78 // [...f = fn](auto tpl) noexcept(noexcept(f)) { return 0; }(0);
79 [...f = fn](auto tpl) noexcept(noexcept(g(fn...))) { return 0; }(0);
80 return [...f = fn](auto tpl) noexcept(noexcept(g(f...))) { return 0; }(0);
83 int v = foo(42);
85 } // namespace GH95735