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