1 // RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - \ 2 // RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=X64 3 // RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - \ 4 // RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=X86 5 6 void try_body(int numerator, int denominator, int *myres) { 7 *myres = numerator / denominator; 8 } 9 // CHECK-LABEL: define void @try_body(i32 %numerator, i32 %denominator, i32* %myres) 10 // CHECK: sdiv i32 11 // CHECK: store i32 %{{.*}}, i32* 12 // CHECK: ret void 13 14 int safe_div(int numerator, int denominator, int *res) { 15 int myres = 0; 16 int success = 1; 17 __try { 18 try_body(numerator, denominator, &myres); 19 } __except (1) { 20 success = -42; 21 } 22 *res = myres; 23 return success; 24 } 25 26 // X64-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res) {{.*}} personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) 27 // X64: invoke void @try_body(i32 %{{.*}}, i32 %{{.*}}, i32* %{{.*}}) #[[NOINLINE:[0-9]+]] 28 // X64: to label %{{.*}} unwind label %[[lpad:[^ ]*]] 29 // 30 // X64: [[lpad]] 31 // X64: landingpad { i8*, i32 } 32 // X64-NEXT: catch i8* null 33 // X64-NOT: br i1 34 // X64: br label %[[except:[^ ]*]] 35 // X64: [[except]] 36 // X64: store i32 -42, i32* %[[success:[^ ]*]] 37 // 38 // X64: %[[res:[^ ]*]] = load i32, i32* %[[success]] 39 // X64: ret i32 %[[res]] 40 41 // X86-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res) {{.*}} personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) 42 // X86: invoke void @try_body(i32 %{{.*}}, i32 %{{.*}}, i32* %{{.*}}) #[[NOINLINE:[0-9]+]] 43 // X86: to label %{{.*}} unwind label %[[lpad:[^ ]*]] 44 // 45 // X86: [[lpad]] 46 // X86: landingpad { i8*, i32 } 47 // X86-NEXT: catch i8* bitcast (i32 ()* @"\01?filt$0@0@safe_div@@" to i8*) 48 // X86-NOT: br i1 49 // X86: br label %[[except:[^ ]*]] 50 // X86: [[except]] 51 // X86: store i32 -42, i32* %[[success:[^ ]*]] 52 // 53 // X86: %[[res:[^ ]*]] = load i32, i32* %[[success]] 54 // X86: ret i32 %[[res]] 55 56 // X86-LABEL: define internal i32 @"\01?filt$0@0@safe_div@@"() 57 // X86: %[[ebp:[^ ]*]] = call i8* @llvm.frameaddress(i32 1) 58 // X86: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 (i32, i32, i32*)* @safe_div to i8*), i8* %[[ebp]]) 59 // X86: call i8* @llvm.localrecover(i8* bitcast (i32 (i32, i32, i32*)* @safe_div to i8*), i8* %[[fp]], i32 0) 60 // X86: load i8*, i8** 61 // X86: load i32*, i32** 62 // X86: load i32, i32* 63 // X86: store i32 %{{.*}}, i32* 64 // X86: ret i32 1 65 66 void j(void); 67 68 int filter_expr_capture(void) { 69 int r = 42; 70 __try { 71 j(); 72 } __except(r = -1) { 73 r = 13; 74 } 75 return r; 76 } 77 78 // CHECK-LABEL: define i32 @filter_expr_capture() 79 // X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) 80 // X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) 81 // X64: call void (...) @llvm.localescape(i32* %[[r:[^ ,]*]]) 82 // X86: call void (...) @llvm.localescape(i32* %[[r:[^ ,]*]], i32* %[[code:[^ ,]*]]) 83 // CHECK: store i32 42, i32* %[[r]] 84 // CHECK: invoke void @j() #[[NOINLINE]] 85 // 86 // CHECK: landingpad 87 // CHECK-NEXT: catch i8* bitcast (i32 ({{.*}})* @"\01?filt$0@0@filter_expr_capture@@" to i8*) 88 // CHECK: store i32 13, i32* %[[r]] 89 // 90 // CHECK: %[[rv:[^ ]*]] = load i32, i32* %[[r]] 91 // CHECK: ret i32 %[[rv]] 92 93 // X64-LABEL: define internal i32 @"\01?filt$0@0@filter_expr_capture@@"(i8* %exception_pointers, i8* %frame_pointer) 94 // X64: call i8* @llvm.localrecover(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %frame_pointer, i32 0) 95 // 96 // X86-LABEL: define internal i32 @"\01?filt$0@0@filter_expr_capture@@"() 97 // X86: %[[ebp:[^ ]*]] = call i8* @llvm.frameaddress(i32 1) 98 // X86: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %[[ebp]]) 99 // X86: call i8* @llvm.localrecover(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %[[fp]], i32 0) 100 // 101 // CHECK: store i32 -1, i32* %{{.*}} 102 // CHECK: ret i32 -1 103 104 int nested_try(void) { 105 int r = 42; 106 __try { 107 __try { 108 j(); 109 r = 0; 110 } __except(_exception_code() == 123) { 111 r = 123; 112 } 113 } __except(_exception_code() == 456) { 114 r = 456; 115 } 116 return r; 117 } 118 // CHECK-LABEL: define i32 @nested_try() 119 // X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) 120 // X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) 121 // CHECK: store i32 42, i32* %[[r:[^ ,]*]] 122 // CHECK: invoke void @j() #[[NOINLINE]] 123 // CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] 124 // 125 // CHECK: [[cont]] 126 // CHECK: store i32 0, i32* %[[r]] 127 // CHECK: br label %[[inner_try_cont:[^ ]*]] 128 // 129 // CHECK: [[lpad]] 130 // CHECK: landingpad { i8*, i32 } 131 // CHECK: catch i8* bitcast (i32 ({{.*}})* @"\01?filt$1@0@nested_try@@" to i8*) 132 // CHECK: catch i8* bitcast (i32 ({{.*}})* @"\01?filt$0@0@nested_try@@" to i8*) 133 // CHECK: store i8* %{{.*}}, i8** %[[ehptr_slot:[^ ]*]] 134 // CHECK: store i32 %{{.*}}, i32* %[[sel_slot:[^ ]*]] 135 // 136 // CHECK: load i32, i32* %[[sel_slot]] 137 // CHECK: call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ({{.*}})* @"\01?filt$1@0@nested_try@@" to i8*)) 138 // CHECK: icmp eq i32 139 // CHECK: br i1 140 // 141 // CHECK: load i32, i32* %[[sel_slot]] 142 // CHECK: call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ({{.*}})* @"\01?filt$0@0@nested_try@@" to i8*)) 143 // CHECK: icmp eq i32 144 // CHECK: br i1 145 // 146 // CHECK: store i32 456, i32* %[[r]] 147 // CHECK: br label %[[outer_try_cont:[^ ]*]] 148 // 149 // CHECK: [[outer_try_cont]] 150 // CHECK: %[[r_load:[^ ]*]] = load i32, i32* %[[r]] 151 // CHECK: ret i32 %[[r_load]] 152 // 153 // CHECK: store i32 123, i32* %[[r]] 154 // CHECK: br label %[[inner_try_cont]] 155 // 156 // CHECK: [[inner_try_cont]] 157 // CHECK: br label %[[outer_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 %[[lpad:[^ ]*]] 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: [[lpad]] 196 // CHECK: landingpad { i8*, i32 } 197 // CHECK-NEXT: cleanup 198 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() 199 // CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]]) 200 // CHECK: resume 201 202 // CHECK: define internal void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} %abnormal_termination, i8* %frame_pointer) 203 // CHECK: call i8* @llvm.localrecover(i8* bitcast (i32 (i32)* @basic_finally to i8*), i8* %frame_pointer, i32 0) 204 // CHECK: load i32, i32* %{{.*}}, align 4 205 // CHECK: add nsw i32 %{{.*}}, 1 206 // CHECK: store i32 %{{.*}}, i32* %{{.*}}, align 4 207 // CHECK: ret void 208 209 int returns_int(void); 210 int except_return(void) { 211 __try { 212 return returns_int(); 213 } __except(1) { 214 return 42; 215 } 216 } 217 // CHECK-LABEL: define i32 @except_return() 218 // CHECK: %[[tmp:[^ ]*]] = invoke i32 @returns_int() 219 // CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] 220 // 221 // CHECK: [[cont]] 222 // CHECK: store i32 %[[tmp]], i32* %[[rv:[^ ]*]] 223 // CHECK: br label %[[retbb:[^ ]*]] 224 // 225 // CHECK: [[lpad]] 226 // CHECK: store i32 42, i32* %[[rv]] 227 // CHECK: br label %[[retbb]] 228 // 229 // CHECK: [[retbb]] 230 // CHECK: %[[r:[^ ]*]] = load i32, i32* %[[rv]] 231 // CHECK: ret i32 %[[r]] 232 233 // CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} } 234