1 // RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-unknown-linux-gnu %s -o - -emit-llvm -O1 \ 2 // RUN: -fexceptions -fcxx-exceptions -mllvm -simplifycfg-sink-common=false | FileCheck %s 3 // 4 // We should emit lifetime.ends for these temporaries in both the 'exception' 5 // and 'normal' paths in functions. 6 // 7 // -O1 is necessary to make lifetime markers appear. 8 9 struct Large { 10 int cs[32]; 11 }; 12 13 Large getLarge(); 14 15 // Used to ensure we emit invokes. 16 struct NontrivialDtor { 17 int i; 18 ~NontrivialDtor(); 19 }; 20 21 // CHECK-LABEL: define{{.*}} void @_Z33cleanupsAreEmittedWithoutTryCatchv 22 void cleanupsAreEmittedWithoutTryCatch() { 23 // CHECK: %[[CLEAN:[^ ]+]] = bitcast %struct.NontrivialDtor* %{{[^ ]+}} to i8* 24 // CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[CLEAN]]) 25 // CHECK: %[[T1:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8* 26 // CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[T1]]) 27 // CHECK-NEXT: invoke void @_Z8getLargev 28 // CHECK-NEXT: to label %[[CONT:[^ ]+]] unwind label %[[LPAD:[^ ]+]] 29 // 30 // CHECK: [[CONT]]: 31 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T1]]) 32 // CHECK: %[[T2:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8* 33 // CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[T2]]) 34 // CHECK-NEXT: invoke void @_Z8getLargev 35 // CHECK-NEXT: to label %[[CONT2:[^ ]+]] unwind label %[[LPAD2:.+]] 36 // 37 // CHECK: [[CONT2]]: 38 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T2]]) 39 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[CLEAN]]) 40 // CHECK: ret void 41 // 42 // CHECK: [[LPAD]]: 43 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T1]]) 44 // CHECK: br label %[[EHCLEANUP:.+]] 45 // 46 // CHECK: [[LPAD2]]: 47 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T2]]) 48 // CHECK: br label %[[EHCLEANUP]] 49 // 50 // CHECK: [[EHCLEANUP]]: 51 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[CLEAN]]) 52 53 NontrivialDtor clean; 54 55 getLarge(); 56 getLarge(); 57 } 58 59 // CHECK-LABEL: define{{.*}} void @_Z30cleanupsAreEmittedWithTryCatchv 60 void cleanupsAreEmittedWithTryCatch() { 61 // CHECK: %[[CLEAN:[^ ]+]] = bitcast %struct.NontrivialDtor* %{{[^ ]+}} to i8* 62 // CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[CLEAN]]) 63 // CHECK: %[[T1:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8* 64 // CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[T1]]) 65 // CHECK-NEXT: invoke void @_Z8getLargev 66 // CHECK-NEXT: to label %[[CONT:[^ ]+]] unwind label %[[LPAD:[^ ]+]] 67 // 68 // CHECK: [[CONT]]: 69 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T1]]) 70 // CHECK: %[[T2:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8* 71 // CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[T2]]) 72 // CHECK-NEXT: invoke void @_Z8getLargev 73 // CHECK-NEXT: to label %[[CONT2:[^ ]+]] unwind label %[[LPAD2:.+]] 74 // 75 // CHECK: [[CONT2]]: 76 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T2]]) 77 // CHECK: br label %[[TRY_CONT:.+]] 78 // 79 // CHECK: [[LPAD]]: 80 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T1]]) 81 // CHECK: br label %[[CATCH:.+]] 82 // 83 // CHECK: [[LPAD2]]: 84 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T2]]) 85 // CHECK: br label %[[CATCH]] 86 // 87 // CHECK: [[CATCH]]: 88 // CHECK-NOT: call void @llvm.lifetime 89 // CHECK: invoke void 90 // CHECK-NEXT: to label %[[TRY_CONT]] unwind label %[[OUTER_LPAD:.+]] 91 // 92 // CHECK: [[TRY_CONT]]: 93 // CHECK: %[[T_OUTER:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8* 94 // CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[T_OUTER]]) 95 // CHECK-NEXT: invoke void @_Z8getLargev 96 // CHECK-NEXT: to label %[[OUTER_CONT:[^ ]+]] unwind label %[[OUTER_LPAD2:.+]] 97 // 98 // CHECK: [[OUTER_CONT]]: 99 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T_OUTER]]) 100 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[CLEAN]]) 101 // CHECK: ret void 102 // 103 // CHECK: [[OUTER_LPAD]]: 104 // CHECK-NOT: call void @llvm.lifetime 105 // CHECK: br label %[[EHCLEANUP:.+]] 106 // 107 // CHECK: [[OUTER_LPAD2]]: 108 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T_OUTER]]) 109 // CHECK: br label %[[EHCLEANUP]] 110 // 111 // CHECK: [[EHCLEANUP]]: 112 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[CLEAN]]) 113 114 NontrivialDtor clean; 115 116 try { 117 getLarge(); 118 getLarge(); 119 } catch (...) {} 120 121 getLarge(); 122 } 123 124 // CHECK-LABEL: define{{.*}} void @_Z39cleanupInTryHappensBeforeCleanupInCatchv 125 void cleanupInTryHappensBeforeCleanupInCatch() { 126 // CHECK: %[[T1:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8* 127 // CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[T1]]) 128 // CHECK-NEXT: invoke void @_Z8getLargev 129 // CHECK-NEXT: to label %[[CONT:[^ ]+]] unwind label %[[LPAD:[^ ]+]] 130 // 131 // CHECK: [[CONT]]: 132 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T1]]) 133 // CHECK: br label %[[TRY_CONT]] 134 // 135 // CHECK: [[LPAD]]: 136 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T1]]) 137 // CHECK: br i1 {{[^,]+}}, label %[[CATCH_INT_MATCH:[^,]+]], label %[[CATCH_ALL:.+]] 138 // 139 // CHECK: [[CATCH_INT_MATCH]]: 140 // CHECK: %[[T2:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8* 141 // CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[T2]]) 142 // CHECK-NEXT: invoke void @_Z8getLargev 143 // CHECK-NEXT: to label %[[CATCH_INT_CONT:[^ ]+]] unwind label %[[CATCH_INT_LPAD:[^ ]+]] 144 // 145 // CHECK: [[CATCH_INT_CONT]]: 146 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T2]]) 147 // CHECK: br label %[[TRY_CONT]] 148 // 149 // CHECK: [[TRY_CONT]]: 150 // CHECK: ret void 151 // 152 // CHECK: [[CATCH_ALL]]: 153 // CHECK: %[[T3:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8* 154 // CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[T3]]) 155 // CHECK-NEXT: invoke void @_Z8getLargev 156 // CHECK-NEXT: to label %[[CATCH_ALL_CONT:[^ ]+]] unwind label %[[CATCH_ALL_LPAD:[^ ]+]] 157 // 158 // CHECK: [[CATCH_ALL_CONT]]: 159 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T3]]) 160 // CHECK: br label %[[TRY_CONT]] 161 // 162 // CHECK: [[CATCH_ALL_LPAD]]: 163 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T3]]) 164 // 165 // CHECK: [[CATCH_INT_LPAD]]: 166 // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T2]]) 167 // CHECK-NOT: call void @llvm.lifetime 168 169 try { 170 getLarge(); 171 } catch (const int &) { 172 getLarge(); 173 } catch (...) { 174 getLarge(); 175 } 176 } 177 178 // FIXME: We don't currently emit lifetime markers for aggregate by-value 179 // temporaries (e.g. given a function `Large combine(Large, Large);` 180 // combine(getLarge(), getLarge()) "leaks" two `Large`s). We probably should. We 181 // also don't emit markers for things like: 182 // 183 // { 184 // Large L = getLarge(); 185 // combine(L, L); 186 // } 187 // 188 // Though this arguably isn't as bad, since we pass a pointer to `L` as one of 189 // the two args. 190