1 // RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -fnew-ms-eh -emit-llvm -o - \ 2 // RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=X64 3 // RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -fnew-ms-eh -emit-llvm -o - \ 4 // RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=X86 5 // RUN: %clang_cc1 %s -triple i686-pc-windows-gnu -fms-extensions -fnew-ms-eh -emit-llvm -o - \ 6 // RUN: | FileCheck %s --check-prefix=X86-GNU 7 // RUN: %clang_cc1 %s -triple x86_64-pc-windows-gnu -fms-extensions -fnew-ms-eh -emit-llvm -o - \ 8 // RUN: | FileCheck %s --check-prefix=X64-GNU 9 10 void try_body(int numerator, int denominator, int *myres) { 11 *myres = numerator / denominator; 12 } 13 // CHECK-LABEL: define void @try_body(i32 %numerator, i32 %denominator, i32* %myres) 14 // CHECK: sdiv i32 15 // CHECK: store i32 %{{.*}}, i32* 16 // CHECK: ret void 17 18 int safe_div(int numerator, int denominator, int *res) { 19 int myres = 0; 20 int success = 1; 21 __try { 22 try_body(numerator, denominator, &myres); 23 } __except (1) { 24 success = -42; 25 } 26 *res = myres; 27 return success; 28 } 29 30 // CHECK-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res) 31 // X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) 32 // X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) 33 // CHECK: invoke void @try_body(i32 %{{.*}}, i32 %{{.*}}, i32* %{{.*}}) #[[NOINLINE:[0-9]+]] 34 // CHECK: to label %{{.*}} unwind label %[[catchpad:[^ ]*]] 35 // 36 // CHECK: [[catchpad]] 37 // X64: %[[padtoken:[^ ]*]] = catchpad within %{{[^ ]*}} [i8* null] 38 // X86: %[[padtoken:[^ ]*]] = catchpad within %{{[^ ]*}} [i8* bitcast (i32 ()* @"\01?filt$0@0@safe_div@@" to i8*)] 39 // CHECK-NEXT: catchret from %[[padtoken]] to label %[[except:[^ ]*]] 40 // 41 // CHECK: [[except]] 42 // CHECK: store i32 -42, i32* %[[success:[^ ]*]] 43 // 44 // CHECK: %[[res:[^ ]*]] = load i32, i32* %[[success]] 45 // CHECK: ret i32 %[[res]] 46 47 // 32-bit SEH needs this filter to save the exception code. 48 // 49 // X86-LABEL: define internal i32 @"\01?filt$0@0@safe_div@@"() 50 // X86: %[[ebp:[^ ]*]] = call i8* @llvm.frameaddress(i32 1) 51 // X86: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 (i32, i32, i32*)* @safe_div to i8*), i8* %[[ebp]]) 52 // X86: call i8* @llvm.localrecover(i8* bitcast (i32 (i32, i32, i32*)* @safe_div to i8*), i8* %[[fp]], i32 0) 53 // X86: load i8*, i8** 54 // X86: load i32*, i32** 55 // X86: load i32, i32* 56 // X86: store i32 %{{.*}}, i32* 57 // X86: ret i32 1 58 59 // Mingw uses msvcrt, so it can also use _except_handler3. 60 // X86-GNU-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res) 61 // X86-GNU-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) 62 // X64-GNU-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res) 63 // X64-GNU-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) 64 65 void j(void); 66 67 int filter_expr_capture(void) { 68 int r = 42; 69 __try { 70 j(); 71 } __except(r = -1) { 72 r = 13; 73 } 74 return r; 75 } 76 77 // CHECK-LABEL: define i32 @filter_expr_capture() 78 // X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) 79 // X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) 80 // X64: call void (...) @llvm.localescape(i32* %[[r:[^ ,]*]]) 81 // X86: call void (...) @llvm.localescape(i32* %[[r:[^ ,]*]], i32* %[[code:[^ ,]*]]) 82 // CHECK: store i32 42, i32* %[[r]] 83 // CHECK: invoke void @j() #[[NOINLINE]] 84 // 85 // CHECK: catchpad within %{{[^ ]*}} [i8* bitcast (i32 ({{.*}})* @"\01?filt$0@0@filter_expr_capture@@" to i8*)] 86 // CHECK: store i32 13, i32* %[[r]] 87 // 88 // CHECK: %[[rv:[^ ]*]] = load i32, i32* %[[r]] 89 // CHECK: ret i32 %[[rv]] 90 91 // X64-LABEL: define internal i32 @"\01?filt$0@0@filter_expr_capture@@"(i8* %exception_pointers, i8* %frame_pointer) 92 // X64: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %frame_pointer) 93 // X64: call i8* @llvm.localrecover(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %[[fp]], i32 0) 94 // 95 // X86-LABEL: define internal i32 @"\01?filt$0@0@filter_expr_capture@@"() 96 // X86: %[[ebp:[^ ]*]] = call i8* @llvm.frameaddress(i32 1) 97 // X86: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %[[ebp]]) 98 // X86: call i8* @llvm.localrecover(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %[[fp]], i32 0) 99 // 100 // CHECK: store i32 -1, i32* %{{.*}} 101 // CHECK: ret i32 -1 102 103 int nested_try(void) { 104 int r = 42; 105 __try { 106 __try { 107 j(); 108 r = 0; 109 } __except(_exception_code() == 123) { 110 r = 123; 111 } 112 } __except(_exception_code() == 456) { 113 r = 456; 114 } 115 return r; 116 } 117 // CHECK-LABEL: define i32 @nested_try() 118 // X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) 119 // X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) 120 // CHECK: store i32 42, i32* %[[r:[^ ,]*]] 121 // CHECK: invoke void @j() #[[NOINLINE]] 122 // CHECK: to label %[[cont:[^ ]*]] unwind label %[[cswitch_inner:[^ ]*]] 123 // 124 // CHECK: [[cswitch_inner]] 125 // CHECK: %[[cs_inner:[^ ]*]] = catchswitch within none [label %[[cpad_inner:[^ ]*]]] unwind label %[[cswitch_outer:[^ ]*]] 126 // 127 // CHECK: [[cswitch_outer]] 128 // CHECK: %[[cs_outer:[^ ]*]] = catchswitch within none [label %[[cpad_outer:[^ ]*]]] unwind to caller 129 // 130 // CHECK: [[cpad_outer]] 131 // CHECK: catchpad within %{{[^ ]*}} [i8* bitcast (i32 ({{.*}})* @"\01?filt$0@0@nested_try@@" to i8*)] 132 // CHECK-NEXT: catchret {{.*}} to label %[[except_outer:[^ ]*]] 133 // 134 // CHECK: [[except_outer]] 135 // CHECK: store i32 456, i32* %[[r]] 136 // CHECK: br label %[[outer_try_cont:[^ ]*]] 137 // 138 // CHECK: [[outer_try_cont]] 139 // CHECK: %[[r_load:[^ ]*]] = load i32, i32* %[[r]] 140 // CHECK: ret i32 %[[r_load]] 141 // 142 // CHECK: [[cpad_inner]] 143 // CHECK: catchpad within %[[cs_inner]] [i8* bitcast (i32 ({{.*}})* @"\01?filt$1@0@nested_try@@" to i8*)] 144 // CHECK-NEXT: catchret {{.*}} to label %[[except_inner:[^ ]*]] 145 // 146 // CHECK: [[except_inner]] 147 // CHECK: store i32 123, i32* %[[r]] 148 // CHECK: br label %[[inner_try_cont:[^ ]*]] 149 // 150 // CHECK: [[inner_try_cont]] 151 // CHECK: br label %[[outer_try_cont]] 152 // 153 // CHECK: [[cont]] 154 // CHECK: store i32 0, i32* %[[r]] 155 // CHECK: br label %[[inner_try_cont]] 156 // 157 // CHECK-LABEL: define internal i32 @"\01?filt$0@0@nested_try@@"({{.*}}) 158 // X86: call i8* @llvm.x86.seh.recoverfp({{.*}}) 159 // CHECK: load i32*, i32** 160 // CHECK: load i32, i32* 161 // CHECK: icmp eq i32 %{{.*}}, 456 162 // 163 // CHECK-LABEL: define internal i32 @"\01?filt$1@0@nested_try@@"({{.*}}) 164 // X86: call i8* @llvm.x86.seh.recoverfp({{.*}}) 165 // CHECK: load i32*, i32** 166 // CHECK: load i32, i32* 167 // CHECK: icmp eq i32 %{{.*}}, 123 168 169 int basic_finally(int g) { 170 __try { 171 j(); 172 } __finally { 173 ++g; 174 } 175 return g; 176 } 177 // CHECK-LABEL: define i32 @basic_finally(i32 %g) 178 // X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) 179 // X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) 180 // CHECK: %[[g_addr:[^ ]*]] = alloca i32, align 4 181 // CHECK: call void (...) @llvm.localescape(i32* %[[g_addr]]) 182 // CHECK: store i32 %g, i32* %[[g_addr]] 183 // 184 // CHECK: invoke void @j() 185 // CHECK: to label %[[cont:[^ ]*]] unwind label %[[cleanuppad:[^ ]*]] 186 // 187 // CHECK: [[cont]] 188 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() 189 // CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 0, i8* %[[fp]]) 190 // CHECK: load i32, i32* %[[g_addr]], align 4 191 // CHECK: ret i32 192 // 193 // CHECK: [[cleanuppad]] 194 // CHECK: %[[padtoken:[^ ]*]] = cleanuppad within none [] 195 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() 196 // CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]]) 197 // CHECK: cleanupret from %[[padtoken]] unwind to caller 198 199 // CHECK: define internal void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} %abnormal_termination, i8* %frame_pointer) 200 // CHECK: call i8* @llvm.localrecover(i8* bitcast (i32 (i32)* @basic_finally to i8*), i8* %frame_pointer, i32 0) 201 // CHECK: load i32, i32* %{{.*}}, align 4 202 // CHECK: add nsw i32 %{{.*}}, 1 203 // CHECK: store i32 %{{.*}}, i32* %{{.*}}, align 4 204 // CHECK: ret void 205 206 int returns_int(void); 207 int except_return(void) { 208 __try { 209 return returns_int(); 210 } __except(1) { 211 return 42; 212 } 213 } 214 // CHECK-LABEL: define i32 @except_return() 215 // CHECK: %[[tmp:[^ ]*]] = invoke i32 @returns_int() 216 // CHECK: to label %[[cont:[^ ]*]] unwind label %[[catchpad:[^ ]*]] 217 // 218 // CHECK: [[catchpad]] 219 // CHECK: catchpad 220 // CHECK: catchret 221 // CHECK: store i32 42, i32* %[[rv:[^ ]*]] 222 // CHECK: br label %[[retbb:[^ ]*]] 223 // 224 // CHECK: [[cont]] 225 // CHECK: store i32 %[[tmp]], i32* %[[rv]] 226 // CHECK: br label %[[retbb]] 227 // 228 // CHECK: [[retbb]] 229 // CHECK: %[[r:[^ ]*]] = load i32, i32* %[[rv]] 230 // CHECK: ret i32 %[[r]] 231 232 233 // PR 24751: don't assert if a variable is used twice in a __finally block. 234 // Also, make sure we don't do redundant work to capture/project it. 235 void finally_capture_twice(int x) { 236 __try { 237 } __finally { 238 int y = x; 239 int z = x; 240 } 241 } 242 // 243 // CHECK-LABEL: define void @finally_capture_twice( 244 // CHECK: [[X:%.*]] = alloca i32, align 4 245 // CHECK: call void (...) @llvm.localescape(i32* [[X]]) 246 // CHECK-NEXT: store i32 {{.*}}, i32* [[X]], align 4 247 // CHECK-NEXT: [[LOCAL:%.*]] = call i8* @llvm.localaddress() 248 // CHECK-NEXT: call void [[FINALLY:@.*]](i8{{ zeroext | }}0, i8* [[LOCAL]]) 249 // CHECK: define internal void [[FINALLY]]( 250 // CHECK: [[LOCAL:%.*]] = call i8* @llvm.localrecover( 251 // CHECK: [[X:%.*]] = bitcast i8* [[LOCAL]] to i32* 252 // CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4 253 // CHECK-NEXT: [[Z:%.*]] = alloca i32, align 4 254 // CHECK-NEXT: store i8* 255 // CHECK-NEXT: store i8 256 // CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[X]], align 4 257 // CHECK-NEXT: store i32 [[T0]], i32* [[Y]], align 4 258 // CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[X]], align 4 259 // CHECK-NEXT: store i32 [[T0]], i32* [[Z]], align 4 260 // CHECK-NEXT: ret void 261 262 int exception_code_in_except(void) { 263 __try { 264 try_body(0, 0, 0); 265 } __except(1) { 266 return _exception_code(); 267 } 268 } 269 270 // CHECK-LABEL: define i32 @exception_code_in_except() 271 // CHECK: %[[ret_slot:[^ ]*]] = alloca i32 272 // CHECK: %[[code_slot:[^ ]*]] = alloca i32 273 // CHECK: invoke void @try_body(i32 0, i32 0, i32* null) 274 // CHECK: %[[pad:[^ ]*]] = catchpad 275 // CHECK: catchret from %[[pad]] 276 // X64: %[[code:[^ ]*]] = call i32 @llvm.eh.exceptioncode(token %[[pad]]) 277 // X64: store i32 %[[code]], i32* %[[code_slot]] 278 // CHECK: %[[ret1:[^ ]*]] = load i32, i32* %[[code_slot]] 279 // CHECK: store i32 %[[ret1]], i32* %[[ret_slot]] 280 // CHECK: %[[ret2:[^ ]*]] = load i32, i32* %[[ret_slot]] 281 // CHECK: ret i32 %[[ret2]] 282 283 // CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} } 284