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