1 // RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s 2 // RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s 3 4 void abort(void) __attribute__((noreturn)); 5 void might_crash(void); 6 void cleanup(void); 7 int check_condition(void); 8 void basic_finally(void) { 9 __try { 10 might_crash(); 11 } __finally { 12 cleanup(); 13 } 14 } 15 16 // CHECK-LABEL: define void @basic_finally() 17 // CHECK: invoke void @might_crash() 18 // CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] 19 // 20 // CHECK: [[invoke_cont]] 21 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() 22 // CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 0, i8* %[[fp]]) 23 // CHECK-NEXT: ret void 24 // 25 // CHECK: [[lpad]] 26 // CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad 27 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() 28 // CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]]) 29 // CHECK-NEXT: cleanupret from %[[pad]] unwind to caller 30 31 // CHECK: define internal void @"\01?fin$0@0@basic_finally@@"({{.*}}) 32 // CHECK-SAME: [[finally_attrs:#[0-9]+]] 33 // CHECK: call void @cleanup() 34 35 // Mostly check that we don't double emit 'r' which would crash. 36 void decl_in_finally(void) { 37 __try { 38 might_crash(); 39 } __finally { 40 int r; 41 } 42 } 43 44 // Ditto, don't crash double emitting 'l'. 45 void label_in_finally(void) { 46 __try { 47 might_crash(); 48 } __finally { 49 l: 50 cleanup(); 51 if (check_condition()) 52 goto l; 53 } 54 } 55 56 // CHECK-LABEL: define void @label_in_finally() 57 // CHECK: invoke void @might_crash() 58 // CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] 59 // 60 // CHECK: [[invoke_cont]] 61 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() 62 // CHECK: call void @"\01?fin$0@0@label_in_finally@@"({{i8( zeroext)?}} 0, i8* %[[fp]]) 63 // CHECK: ret void 64 65 // CHECK: define internal void @"\01?fin$0@0@label_in_finally@@"({{.*}}) 66 // CHECK-SAME: [[finally_attrs]] 67 // CHECK: br label %[[l:[^ ]*]] 68 // 69 // CHECK: [[l]] 70 // CHECK: call void @cleanup() 71 // CHECK: call i32 @check_condition() 72 // CHECK: br i1 {{.*}}, label 73 // CHECK: br label %[[l]] 74 75 int crashed; 76 void use_abnormal_termination(void) { 77 __try { 78 might_crash(); 79 } __finally { 80 crashed = __abnormal_termination(); 81 } 82 } 83 84 // CHECK-LABEL: define void @use_abnormal_termination() 85 // CHECK: invoke void @might_crash() 86 // CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] 87 // 88 // CHECK: [[invoke_cont]] 89 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() 90 // CHECK: call void @"\01?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} 0, i8* %[[fp]]) 91 // CHECK: ret void 92 // 93 // CHECK: [[lpad]] 94 // CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad 95 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() 96 // CHECK: call void @"\01?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} 1, i8* %[[fp]]) 97 // CHECK-NEXT: cleanupret from %[[pad]] unwind to caller 98 99 // CHECK: define internal void @"\01?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} %[[abnormal:abnormal_termination]], i8* %frame_pointer) 100 // CHECK-SAME: [[finally_attrs]] 101 // CHECK: %[[abnormal_zext:[^ ]*]] = zext i8 %[[abnormal]] to i32 102 // CHECK: store i32 %[[abnormal_zext]], i32* @crashed 103 // CHECK-NEXT: ret void 104 105 void noreturn_noop_finally() { 106 __try { 107 __noop(); 108 } __finally { 109 abort(); 110 } 111 } 112 113 // CHECK-LABEL: define void @noreturn_noop_finally() 114 // CHECK: call void @"\01?fin$0@0@noreturn_noop_finally@@"({{.*}}) 115 // CHECK: ret void 116 117 // CHECK: define internal void @"\01?fin$0@0@noreturn_noop_finally@@"({{.*}}) 118 // CHECK-SAME: [[finally_attrs]] 119 // CHECK: call void @abort() 120 // CHECK: unreachable 121 122 void noreturn_finally() { 123 __try { 124 might_crash(); 125 } __finally { 126 abort(); 127 } 128 } 129 130 // CHECK-LABEL: define void @noreturn_finally() 131 // CHECK: invoke void @might_crash() 132 // CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] 133 // 134 // CHECK: [[cont]] 135 // CHECK: call void @"\01?fin$0@0@noreturn_finally@@"({{.*}}) 136 // CHECK: ret void 137 // 138 // CHECK: [[lpad]] 139 // CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad 140 // CHECK: call void @"\01?fin$0@0@noreturn_finally@@"({{.*}}) 141 // CHECK-NEXT: cleanupret from %[[pad]] unwind to caller 142 143 // CHECK: define internal void @"\01?fin$0@0@noreturn_finally@@"({{.*}}) 144 // CHECK-SAME: [[finally_attrs]] 145 // CHECK: call void @abort() 146 // CHECK: unreachable 147 148 int finally_with_return() { 149 __try { 150 return 42; 151 } __finally { 152 } 153 } 154 // CHECK-LABEL: define i32 @finally_with_return() 155 // CHECK: call void @"\01?fin$0@0@finally_with_return@@"({{.*}}) 156 // CHECK-NEXT: ret i32 42 157 158 // CHECK: define internal void @"\01?fin$0@0@finally_with_return@@"({{.*}}) 159 // CHECK-SAME: [[finally_attrs]] 160 // CHECK-NOT: br i1 161 // CHECK-NOT: br label 162 // CHECK: ret void 163 164 int nested___finally___finally() { 165 __try { 166 __try { 167 } __finally { 168 return 1; 169 } 170 } __finally { 171 // Intentionally no return here. 172 } 173 return 0; 174 } 175 176 // CHECK-LABEL: define i32 @nested___finally___finally 177 // CHECK: invoke void @"\01?fin$1@0@nested___finally___finally@@"({{.*}}) 178 // CHECK: to label %[[outercont:[^ ]*]] unwind label %[[lpad:[^ ]*]] 179 // 180 // CHECK: [[outercont]] 181 // CHECK: call void @"\01?fin$0@0@nested___finally___finally@@"({{.*}}) 182 // CHECK-NEXT: ret i32 0 183 // 184 // CHECK: [[lpad]] 185 // CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad 186 // CHECK: call void @"\01?fin$0@0@nested___finally___finally@@"({{.*}}) 187 // CHECK-NEXT: cleanupret from %[[pad]] unwind to caller 188 189 // CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally@@"({{.*}}) 190 // CHECK-SAME: [[finally_attrs]] 191 // CHECK: ret void 192 193 // CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally@@"({{.*}}) 194 // CHECK-SAME: [[finally_attrs]] 195 // CHECK: unreachable 196 197 // FIXME: Our behavior seems suspiciously different. 198 199 int nested___finally___finally_with_eh_edge() { 200 __try { 201 __try { 202 might_crash(); 203 } __finally { 204 return 899; 205 } 206 } __finally { 207 // Intentionally no return here. 208 } 209 return 912; 210 } 211 // CHECK-LABEL: define i32 @nested___finally___finally_with_eh_edge 212 // CHECK: invoke void @might_crash() 213 // CHECK-NEXT: to label %[[invokecont:[^ ]*]] unwind label %[[lpad1:[^ ]*]] 214 // 215 // [[invokecont]] 216 // CHECK: invoke void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}}) 217 // CHECK-NEXT: to label %[[outercont:[^ ]*]] unwind label %[[lpad2:[^ ]*]] 218 // 219 // CHECK: [[outercont]] 220 // CHECK: call void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}}) 221 // CHECK-NEXT: ret i32 912 222 // 223 // CHECK: [[lpad1]] 224 // CHECK-NEXT: %[[innerpad:[^ ]*]] = cleanuppad 225 // CHECK: invoke void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}}) 226 // CHECK-NEXT: label %[[innercleanupretbb:[^ ]*]] unwind label %[[lpad2:[^ ]*]] 227 // 228 // CHECK: [[innercleanupretbb]] 229 // CHECK-NEXT: cleanupret from %[[innerpad]] unwind label %[[lpad2]] 230 // 231 // CHECK: [[lpad2]] 232 // CHECK-NEXT: %[[outerpad:[^ ]*]] = cleanuppad 233 // CHECK: call void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}}) 234 // CHECK-NEXT: cleanupret from %[[outerpad]] unwind to caller 235 236 // CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}}) 237 // CHECK-SAME: [[finally_attrs]] 238 // CHECK: ret void 239 240 // CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}}) 241 // CHECK-SAME: [[finally_attrs]] 242 // CHECK: unreachable 243 244 void finally_within_finally() { 245 __try { 246 might_crash(); 247 } __finally { 248 __try { 249 might_crash(); 250 } __finally { 251 } 252 } 253 } 254 255 // CHECK-LABEL: define void @finally_within_finally( 256 // CHECK: invoke void @might_crash( 257 258 // CHECK: call void @"\01?fin$0@0@finally_within_finally@@"( 259 // CHECK: call void @"\01?fin$0@0@finally_within_finally@@"({{.*}}) [ "funclet"( 260 261 // CHECK-LABEL: define internal void @"\01?fin$0@0@finally_within_finally@@"({{[^)]*}}) 262 // CHECK-SAME: [[finally_attrs]] 263 // CHECK: invoke void @might_crash( 264 265 // CHECK: call void @"\01?fin$1@0@finally_within_finally@@"( 266 // CHECK: call void @"\01?fin$1@0@finally_within_finally@@"({{.*}}) [ "funclet"( 267 268 // CHECK-LABEL: define internal void @"\01?fin$1@0@finally_within_finally@@"({{[^)]*}}) 269 // CHECK-SAME: [[finally_attrs]] 270 271 // Look for the absence of noinline. Enum attributes come first, so check that 272 // a string attribute is the first to verify that no enum attributes are 273 // present. 274 // CHECK: attributes [[finally_attrs]] = { "{{.*}}" } 275