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 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>() { return ^ X () [[clang::vectorcall]] { 207 T t; 208 return t; 209 }; }()(); 210 } 211