1 // RUN: %clang_cc1 -std=c++20 -fblocks -Wno-return-stack-address -triple x86_64-unknown-unknown-gnu -emit-llvm -O1 -o - %s | FileCheck %s 2 3 struct alignas(4) 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 void @llvm.lifetime.end 33 // CHECK-NEXT: ret void 34 L(3, t, T); 35 36 // CHECK-LABEL: define{{.*}} void @_Z2l4v 37 // CHECK: call {{.*}} @_ZN1XC1Ev 38 // CHECK-NEXT: call void @llvm.lifetime.end 39 // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_ 40 // CHECK-NEXT: call void @llvm.lifetime.end 41 // CHECK-NEXT: ret void 42 L(4, t, T&); 43 44 // CHECK-LABEL: define{{.*}} void @_Z2l5v 45 // CHECK: call {{.*}} @_ZN1XC1Ev 46 // CHECK-NEXT: call {{.*}} @_ZN1XC1EOS_ 47 // CHECK-NEXT: call void @llvm.lifetime.end 48 // CHECK-NEXT: call void @llvm.lifetime.end 49 // CHECK-NEXT: ret void 50 L(5, t, auto); 51 52 // CHECK-LABEL: define{{.*}} void @_Z2l6v 53 // CHECK: call {{.*}} @_ZN1XC1Ev 54 // CHECK-NEXT: call void @llvm.lifetime.end 55 // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_ 56 // CHECK-NEXT: call void @llvm.lifetime.end 57 // CHECK-NEXT: ret void 58 L(6, t, auto&); 59 60 // CHECK-LABEL: define{{.*}} void @_Z2l7v 61 // CHECK: call {{.*}} @_ZN1XC1Ev 62 // CHECK-NEXT: call {{.*}} @_ZN1XC1EOS_ 63 // CHECK-NEXT: call void @llvm.lifetime.end 64 // CHECK-NEXT: call void @llvm.lifetime.end 65 // CHECK-NEXT: ret void 66 L(7, t, decltype(auto)); 67 68 // CHECK-LABEL: define{{.*}} void @_Z2l8v 69 // CHECK: call {{.*}} @_ZN1XC1Ev 70 // CHECK-NEXT: call void @llvm.lifetime.end 71 // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_ 72 // CHECK-NEXT: call void @llvm.lifetime.end 73 // CHECK-NEXT: ret void 74 L(8, (t), decltype(auto)); 75 76 #undef L 77 78 #define F(A, B, C) template<class T = X> static inline auto tf##A() -> C { \ 79 T t; \ 80 return B; \ 81 } \ 82 void f##A() { auto t = tf##A(); } \ 83 84 // CHECK-LABEL: define{{.*}} void @_Z2f1v 85 // CHECK: call {{.*}} @_ZN1XC1Ev 86 // CHECK-NEXT: call void @llvm.lifetime.end 87 // CHECK-NEXT: ret void 88 F(1, t, X); 89 90 // CHECK-LABEL: define{{.*}} void @_Z2f2v 91 // CHECK: call {{.*}} @_ZN1XC1Ev 92 // CHECK-NEXT: call void @llvm.lifetime.end 93 // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_ 94 // CHECK-NEXT: call void @llvm.lifetime.end 95 // CHECK-NEXT: ret void 96 F(2, t, X&); 97 98 // CHECK-LABEL: define{{.*}} void @_Z2f3v 99 // CHECK: call {{.*}} @_ZN1XC1Ev 100 // CHECK-NEXT: call void @llvm.lifetime.end 101 // CHECK-NEXT: ret void 102 F(3, t, T); 103 104 // CHECK-LABEL: define{{.*}} void @_Z2f4v 105 // CHECK: call {{.*}} @_ZN1XC1Ev 106 // CHECK-NEXT: call void @llvm.lifetime.end 107 // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_ 108 // CHECK-NEXT: call void @llvm.lifetime.end 109 // CHECK-NEXT: ret void 110 F(4, t, T&); 111 112 // CHECK-LABEL: define{{.*}} void @_Z2f5v 113 // CHECK: call {{.*}} @_ZN1XC1Ev 114 // CHECK-NEXT: call {{.*}} @_ZN1XC1EOS_ 115 // CHECK-NEXT: call void @llvm.lifetime.end 116 // CHECK-NEXT: call void @llvm.lifetime.end 117 // CHECK-NEXT: ret void 118 F(5, t, auto); 119 120 // CHECK-LABEL: define{{.*}} void @_Z2f6v 121 // CHECK: call {{.*}} @_ZN1XC1Ev 122 // CHECK-NEXT: call void @llvm.lifetime.end 123 // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_ 124 // CHECK-NEXT: call void @llvm.lifetime.end 125 // CHECK-NEXT: ret void 126 F(6, t, auto&); 127 128 // CHECK-LABEL: define{{.*}} void @_Z2f7v 129 // CHECK: call {{.*}} @_ZN1XC1Ev 130 // CHECK-NEXT: call {{.*}} @_ZN1XC1EOS_ 131 // CHECK-NEXT: call void @llvm.lifetime.end 132 // CHECK-NEXT: call void @llvm.lifetime.end 133 // CHECK-NEXT: ret void 134 F(7, t, decltype(auto)); 135 136 // CHECK-LABEL: define{{.*}} void @_Z2f8v 137 // CHECK: call {{.*}} @_ZN1XC1Ev 138 // CHECK-NEXT: call void @llvm.lifetime.end 139 // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_ 140 // CHECK-NEXT: call void @llvm.lifetime.end 141 // CHECK-NEXT: ret void 142 F(8, (t), decltype(auto)); 143 144 #undef F 145 146 #define B(A, B) void b##A() { \ 147 auto t = []<class T = X>() { return ^ B () { \ 148 T t; \ 149 return t; \ 150 }; }()(); \ 151 } 152 153 // CHECK-LABEL: define{{.*}} void @_Z2b1v 154 // CHECK: call {{.*}} @_ZN1XC1Ev 155 // CHECK-NEXT: call void @llvm.lifetime.end 156 // CHECK-NEXT: ret void 157 B(1, X); 158 159 // CHECK-LABEL: define{{.*}} void @_Z2b2v 160 // CHECK: call {{.*}} @_ZN1XC1Ev 161 // CHECK-NEXT: call void @llvm.lifetime.end 162 // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_ 163 // CHECK-NEXT: call void @llvm.lifetime.end 164 // CHECK-NEXT: ret void 165 B(2, X&); 166 167 // CHECK-LABEL: define{{.*}} void @_Z2b3v 168 // CHECK: call {{.*}} @_ZN1XC1Ev 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 191 // CHECK-LABEL: define{{.*}} void @_Z6f_attrv 192 // CHECK: call {{.*}} @_ZN1XC1Ev 193 // CHECK-NEXT: call void @llvm.lifetime.end 194 // CHECK-NEXT: ret void 195 template<class T = X> [[gnu::cdecl]] static inline auto tf_attr() -> X { 196 T t; 197 return t; 198 } 199 void f_attr() { auto t = tf_attr(); } 200 201 // CHECK-LABEL: define{{.*}} void @_Z6b_attrv 202 // CHECK: call {{.*}} @_ZN1XC1Ev 203 // CHECK-NEXT: call void @llvm.lifetime.end 204 // CHECK-NEXT: ret void 205 void b_attr() { 206 auto t = []<class T = X>() { 207 return ^X() [[clang::vectorcall]] { 208 T t; 209 return t; 210 }; 211 }()(); 212 } 213 214 namespace test_alignas { 215 216 template <int A> X t1() { 217 X a [[gnu::aligned(A)]]; 218 return a; 219 } 220 221 // CHECK-LABEL: define{{.*}} void @_ZN12test_alignas2t1ILi1EEE1Xv 222 // CHECK: call {{.*}} @_ZN1XC1Ev 223 // CHECK-NEXT: ret void 224 template X t1<1>(); 225 226 // CHECK-LABEL: define{{.*}} void @_ZN12test_alignas2t1ILi4EEE1Xv 227 // CHECK: call {{.*}} @_ZN1XC1Ev 228 // CHECK-NEXT: ret void 229 template X t1<4>(); 230 231 // CHECK-LABEL: define{{.*}} void @_ZN12test_alignas2t1ILi8EEE1Xv 232 // CHECK: call {{.*}} @_ZN1XC1Ev 233 // CHECK-NEXT: call {{.*}} @_ZN1XC1EOS_ 234 // CHECK-NEXT: call void @llvm.lifetime.end 235 template X t1<8>(); 236 237 template <int A> X t2() { 238 X a [[gnu::aligned(1)]] [[gnu::aligned(A)]] [[gnu::aligned(2)]]; 239 return a; 240 } 241 242 // CHECK-LABEL: define{{.*}} void @_ZN12test_alignas2t2ILi1EEE1Xv 243 // CHECK: call {{.*}} @_ZN1XC1Ev 244 // CHECK-NEXT: ret void 245 template X t2<1>(); 246 247 // CHECK-LABEL: define{{.*}} void @_ZN12test_alignas2t2ILi4EEE1Xv 248 // CHECK: call {{.*}} @_ZN1XC1Ev 249 // CHECK-NEXT: ret void 250 template X t2<4>(); 251 252 // CHECK-LABEL: define{{.*}} void @_ZN12test_alignas2t2ILi8EEE1Xv 253 // CHECK: call {{.*}} @_ZN1XC1Ev 254 // CHECK-NEXT: call {{.*}} @_ZN1XC1EOS_ 255 // CHECK-NEXT: call void @llvm.lifetime.end 256 template X t2<8>(); 257 258 // CHECK-LABEL: define{{.*}} void @_ZN12test_alignas2t3Ev 259 // CHECK: call {{.*}} @_ZN1XC1Ev 260 // CHECK-NEXT: ret void 261 X t3() { 262 X a [[gnu::aligned(1)]]; 263 return a; 264 } 265 266 // CHECK-LABEL: define{{.*}} void @_ZN12test_alignas2t4Ev 267 // CHECK: call {{.*}} @_ZN1XC1Ev 268 // CHECK-NEXT: call {{.*}} @_ZN1XC1EOS_ 269 // CHECK-NEXT: call void @llvm.lifetime.end 270 X t4() { 271 X a [[gnu::aligned(8)]]; 272 return a; 273 } 274 275 // CHECK-LABEL: define{{.*}} void @_ZN12test_alignas2t5Ev 276 // CHECK: call {{.*}} @_ZN1XC1Ev 277 // CHECK-NEXT: call {{.*}} @_ZN1XC1EOS_ 278 // CHECK-NEXT: call void @llvm.lifetime.end 279 X t5() { 280 X a [[gnu::aligned(1)]] [[gnu::aligned(8)]]; 281 return a; 282 } 283 284 } // namespace test_alignas 285 286 namespace PR51862 { 287 288 template <class T> T test() { 289 T a; 290 T b; 291 if (0) 292 return a; 293 return b; 294 } 295 296 struct A { 297 A(); 298 A(A &); 299 A(int); 300 operator int(); 301 }; 302 303 // CHECK-LABEL: define{{.*}} void @_ZN7PR518624testINS_1AEEET_v 304 // CHECK: call noundef i32 @_ZN7PR518621AcviEv 305 // CHECK-NEXT: call void @_ZN7PR518621AC1Ei 306 // CHECK-NEXT: call void @llvm.lifetime.end 307 template A test<A>(); 308 309 struct BSub {}; 310 struct B : BSub { 311 B(); 312 B(B &); 313 B(const BSub &); 314 }; 315 316 // CHECK-LABEL: define{{.*}} void @_ZN7PR518624testINS_1BEEET_v 317 // CHECK: call void @_ZN7PR518621BC1ERKNS_4BSubE 318 // CHECK-NEXT: call void @llvm.lifetime.end 319 template B test<B>(); 320 321 } // namespace PR51862 322