1 // RUN: %clang_cc1 -std=c++20 -fblocks -Wno-return-stack-address -triple x86_64-unknown-unknown-gnu -emit-llvm -O1 -fexperimental-new-pass-manager -o - %s | FileCheck %s
2 
3 struct X {
4     X();
5     X(const X&);
6     X(X&&);
7 };
8 
9 #define L(A, B, C) void l##A() {    \
10   auto t = []<class T = X>() -> C { \
11     T t;                            \
12     return B;                       \
13   }();                              \
14 }
15 
16 // CHECK-LABEL: define{{.*}} void @_Z2l1v
17 // CHECK:       call {{.*}} @_ZN1XC1Ev
18 // CHECK-NEXT:  call void @llvm.lifetime.end
19 // CHECK-NEXT:  ret void
20 L(1, t, X);
21 
22 // CHECK-LABEL: define{{.*}} void @_Z2l2v
23 // CHECK:       call {{.*}} @_ZN1XC1Ev
24 // CHECK-NEXT:  call void @llvm.lifetime.end
25 // CHECK-NEXT:  call {{.*}} @_ZN1XC1ERKS_
26 // CHECK-NEXT:  call void @llvm.lifetime.end
27 // CHECK-NEXT:  ret void
28 L(2, t, X&);
29 
30 // CHECK-LABEL: define{{.*}} void @_Z2l3v
31 // CHECK:       call {{.*}} @_ZN1XC1Ev
32 // CHECK-NEXT:  call {{.*}} @_ZN1XC1EOS_
33 // CHECK-NEXT:  call void @llvm.lifetime.end
34 // CHECK-NEXT:  call void @llvm.lifetime.end
35 // CHECK-NEXT:  ret void
36 L(3, t, T);
37 
38 // CHECK-LABEL: define{{.*}} void @_Z2l4v
39 // CHECK:       call {{.*}} @_ZN1XC1Ev
40 // CHECK-NEXT:  call void @llvm.lifetime.end
41 // CHECK-NEXT:  call {{.*}} @_ZN1XC1ERKS_
42 // CHECK-NEXT:  call void @llvm.lifetime.end
43 // CHECK-NEXT:  ret void
44 L(4, t, T&);
45 
46 // CHECK-LABEL: define{{.*}} void @_Z2l5v
47 // CHECK:       call {{.*}} @_ZN1XC1Ev
48 // CHECK-NEXT:  call {{.*}} @_ZN1XC1EOS_
49 // CHECK-NEXT:  call void @llvm.lifetime.end
50 // CHECK-NEXT:  call void @llvm.lifetime.end
51 // CHECK-NEXT:  ret void
52 L(5, t, auto);
53 
54 // CHECK-LABEL: define{{.*}} void @_Z2l6v
55 // CHECK:       call {{.*}} @_ZN1XC1Ev
56 // CHECK-NEXT:  call void @llvm.lifetime.end
57 // CHECK-NEXT:  call {{.*}} @_ZN1XC1ERKS_
58 // CHECK-NEXT:  call void @llvm.lifetime.end
59 // CHECK-NEXT:  ret void
60 L(6, t, auto&);
61 
62 // CHECK-LABEL: define{{.*}} void @_Z2l7v
63 // CHECK:       call {{.*}} @_ZN1XC1Ev
64 // CHECK-NEXT:  call {{.*}} @_ZN1XC1EOS_
65 // CHECK-NEXT:  call void @llvm.lifetime.end
66 // CHECK-NEXT:  call void @llvm.lifetime.end
67 // CHECK-NEXT:  ret void
68 L(7, t, decltype(auto));
69 
70 // CHECK-LABEL: define{{.*}} void @_Z2l8v
71 // CHECK:       call {{.*}} @_ZN1XC1Ev
72 // CHECK-NEXT:  call void @llvm.lifetime.end
73 // CHECK-NEXT:  call {{.*}} @_ZN1XC1ERKS_
74 // CHECK-NEXT:  call void @llvm.lifetime.end
75 // CHECK-NEXT:  ret void
76 L(8, (t), decltype(auto));
77 
78 #undef L
79 
80 #define F(A, B, C) template<class T = X> static inline auto tf##A() -> C { \
81     T t;                                                                   \
82     return B;                                                              \
83 }                                                                          \
84 void f##A() { auto t = tf##A(); }                                          \
85 
86 // CHECK-LABEL: define{{.*}} void @_Z2f1v
87 // CHECK:       call {{.*}} @_ZN1XC1Ev
88 // CHECK-NEXT:  call void @llvm.lifetime.end
89 // CHECK-NEXT:  ret void
90 F(1, t, X);
91 
92 // CHECK-LABEL: define{{.*}} void @_Z2f2v
93 // CHECK:       call {{.*}} @_ZN1XC1Ev
94 // CHECK-NEXT:  call void @llvm.lifetime.end
95 // CHECK-NEXT:  call {{.*}} @_ZN1XC1ERKS_
96 // CHECK-NEXT:  call void @llvm.lifetime.end
97 // CHECK-NEXT:  ret void
98 F(2, t, X&);
99 
100 // CHECK-LABEL: define{{.*}} void @_Z2f3v
101 // CHECK:       call {{.*}} @_ZN1XC1Ev
102 // CHECK-NEXT:  call void @llvm.lifetime.end
103 // CHECK-NEXT:  ret void
104 F(3, t, T);
105 
106 // CHECK-LABEL: define{{.*}} void @_Z2f4v
107 // CHECK:       call {{.*}} @_ZN1XC1Ev
108 // CHECK-NEXT:  call void @llvm.lifetime.end
109 // CHECK-NEXT:  call {{.*}} @_ZN1XC1ERKS_
110 // CHECK-NEXT:  call void @llvm.lifetime.end
111 // CHECK-NEXT:  ret void
112 F(4, t, T&);
113 
114 // CHECK-LABEL: define{{.*}} void @_Z2f5v
115 // CHECK:       call {{.*}} @_ZN1XC1Ev
116 // CHECK-NEXT:  call {{.*}} @_ZN1XC1EOS_
117 // CHECK-NEXT:  call void @llvm.lifetime.end
118 // CHECK-NEXT:  call void @llvm.lifetime.end
119 // CHECK-NEXT:  ret void
120 F(5, t, auto);
121 
122 // CHECK-LABEL: define{{.*}} void @_Z2f6v
123 // CHECK:       call {{.*}} @_ZN1XC1Ev
124 // CHECK-NEXT:  call void @llvm.lifetime.end
125 // CHECK-NEXT:  call {{.*}} @_ZN1XC1ERKS_
126 // CHECK-NEXT:  call void @llvm.lifetime.end
127 // CHECK-NEXT:  ret void
128 F(6, t, auto&);
129 
130 // CHECK-LABEL: define{{.*}} void @_Z2f7v
131 // CHECK:       call {{.*}} @_ZN1XC1Ev
132 // CHECK-NEXT:  call {{.*}} @_ZN1XC1EOS_
133 // CHECK-NEXT:  call void @llvm.lifetime.end
134 // CHECK-NEXT:  call void @llvm.lifetime.end
135 // CHECK-NEXT:  ret void
136 F(7, t, decltype(auto));
137 
138 // CHECK-LABEL: define{{.*}} void @_Z2f8v
139 // CHECK:       call {{.*}} @_ZN1XC1Ev
140 // CHECK-NEXT:  call void @llvm.lifetime.end
141 // CHECK-NEXT:  call {{.*}} @_ZN1XC1ERKS_
142 // CHECK-NEXT:  call void @llvm.lifetime.end
143 // CHECK-NEXT:  ret void
144 F(8, (t), decltype(auto));
145 
146 #undef F
147 
148 #define B(A, B) void b##A() { \
149   auto t = []<class T = X>() { return ^ B () { \
150       T t;                                     \
151       return t;                                \
152   }; }()();                                    \
153 }
154 
155 //B(1, X); // Uncomment this line at your own peril ;)
156 
157 // CHECK-LABEL: define{{.*}} void @_Z2b2v
158 // CHECK:       call {{.*}} @_ZN1XC1Ev
159 // CHECK-NEXT:  call void @llvm.lifetime.end
160 // CHECK-NEXT:  call {{.*}} @_ZN1XC1ERKS_
161 // CHECK-NEXT:  call void @llvm.lifetime.end
162 // CHECK-NEXT:  ret void
163 B(2, X&);
164 
165 // CHECK-LABEL: define{{.*}} void @_Z2b3v
166 // CHECK:       call {{.*}} @_ZN1XC1Ev
167 // CHECK-NEXT:  call {{.*}} @_ZN1XC1EOS_
168 // CHECK-NEXT:  call void @llvm.lifetime.end
169 // CHECK-NEXT:  call void @llvm.lifetime.end
170 // CHECK-NEXT:  ret void
171 B(3, T);
172 
173 // CHECK-LABEL: define{{.*}} void @_Z2b4v
174 // CHECK:       call {{.*}} @_ZN1XC1Ev
175 // CHECK-NEXT:  call void @llvm.lifetime.end
176 // CHECK-NEXT:  call {{.*}} @_ZN1XC1ERKS_
177 // CHECK-NEXT:  call void @llvm.lifetime.end
178 // CHECK-NEXT:  ret void
179 B(4, T&);
180 
181 // CHECK-LABEL: define{{.*}} void @_Z2b5v
182 // CHECK:       call {{.*}} @_ZN1XC1Ev
183 // CHECK-NEXT:  call {{.*}} @_ZN1XC1EOS_
184 // CHECK-NEXT:  call void @llvm.lifetime.end
185 // CHECK-NEXT:  call void @llvm.lifetime.end
186 // CHECK-NEXT:  ret void
187 B(5, );
188 
189 #undef B
190