• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // RUN: %clang_cc1 %s -triple i686-pc-windows-gnu -fms-extensions -emit-llvm -o - \
6 // RUN:         | FileCheck %s --check-prefix=X86-GNU
7 // RUN: %clang_cc1 %s -triple x86_64-pc-windows-gnu -fms-extensions -emit-llvm -o - \
8 // RUN:         | FileCheck %s --check-prefix=X64-GNU
9 
try_body(int numerator,int denominator,int * myres)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 
safe_div(int numerator,int denominator,int * res)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 
filter_expr_capture(void)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 
nested_try(void)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 
basic_finally(int g)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);
except_return(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.
finally_capture_twice(int x)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 
exception_code_in_except(void)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