blob: a0a1dbccd1580ddc32803bad3d915af02580d2ad [file] [log] [blame]
David Majnemer4ff6f732016-02-20 09:23:41 +00001// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - \
Reid Kleckner9fe7f232015-07-07 00:36:30 +00002// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=X64
David Majnemer4ff6f732016-02-20 09:23:41 +00003// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - \
Reid Kleckner8819a402015-07-10 00:16:25 +00004// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=X86
David Majnemer4ff6f732016-02-20 09:23:41 +00005// RUN: %clang_cc1 %s -triple i686-pc-windows-gnu -fms-extensions -emit-llvm -o - \
Reid Kleckner129552b2015-10-08 01:13:52 +00006// RUN: | FileCheck %s --check-prefix=X86-GNU
David Majnemer4ff6f732016-02-20 09:23:41 +00007// RUN: %clang_cc1 %s -triple x86_64-pc-windows-gnu -fms-extensions -emit-llvm -o - \
Reid Kleckner129552b2015-10-08 01:13:52 +00008// RUN: | FileCheck %s --check-prefix=X64-GNU
Reid Kleckner543a16c2013-09-16 21:46:30 +00009
Reid Kleckner1d59f992015-01-22 01:36:17 +000010void 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
Reid Kleckner543a16c2013-09-16 21:46:30 +000017
Reid Kleckner1d59f992015-01-22 01:36:17 +000018int safe_div(int numerator, int denominator, int *res) {
Reid Kleckner543a16c2013-09-16 21:46:30 +000019 int myres = 0;
Reid Kleckner1d59f992015-01-22 01:36:17 +000020 int success = 1;
Reid Kleckner543a16c2013-09-16 21:46:30 +000021 __try {
Reid Kleckner1d59f992015-01-22 01:36:17 +000022 try_body(numerator, denominator, &myres);
Reid Kleckner543a16c2013-09-16 21:46:30 +000023 } __except (1) {
Reid Kleckner1d59f992015-01-22 01:36:17 +000024 success = -42;
Reid Kleckner543a16c2013-09-16 21:46:30 +000025 }
26 *res = myres;
Reid Kleckner1d59f992015-01-22 01:36:17 +000027 return success;
Reid Kleckner543a16c2013-09-16 21:46:30 +000028}
Reid Kleckner9fe7f232015-07-07 00:36:30 +000029
Reid Kleckner129552b2015-10-08 01:13:52 +000030// 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:[^ ]*]]
Reid Kleckner1d59f992015-01-22 01:36:17 +000035//
Reid Kleckner129552b2015-10-08 01:13:52 +000036// CHECK: [[catchpad]]
David Majnemer4e52d6f2015-12-12 05:39:21 +000037// 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:[^ ]*]]
Reid Kleckner129552b2015-10-08 01:13:52 +000040//
41// CHECK: [[except]]
42// CHECK: store i32 -42, i32* %[[success:[^ ]*]]
43//
44// CHECK: %[[res:[^ ]*]] = load i32, i32* %[[success]]
45// CHECK: ret i32 %[[res]]
Reid Kleckner9fe7f232015-07-07 00:36:30 +000046
Reid Kleckner129552b2015-10-08 01:13:52 +000047// 32-bit SEH needs this filter to save the exception code.
Reid Kleckner9fe7f232015-07-07 00:36:30 +000048//
Reid Kleckner9fe7f232015-07-07 00:36:30 +000049// 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]])
Reid Kleckner98cb8ba2015-07-07 22:26:07 +000052// X86: call i8* @llvm.localrecover(i8* bitcast (i32 (i32, i32, i32*)* @safe_div to i8*), i8* %[[fp]], i32 0)
Reid Kleckner9fe7f232015-07-07 00:36:30 +000053// X86: load i8*, i8**
54// X86: load i32*, i32**
55// X86: load i32, i32*
56// X86: store i32 %{{.*}}, i32*
57// X86: ret i32 1
Reid Kleckner1d59f992015-01-22 01:36:17 +000058
Reid Kleckner129552b2015-10-08 01:13:52 +000059// 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
Reid Kleckner1d59f992015-01-22 01:36:17 +000065void j(void);
66
Reid Kleckner3a417c32015-01-30 22:16:45 +000067int filter_expr_capture(void) {
Reid Kleckner1d59f992015-01-22 01:36:17 +000068 int r = 42;
69 __try {
70 j();
Reid Klecknere0bca752015-04-27 23:14:24 +000071 } __except(r = -1) {
Reid Kleckner1d59f992015-01-22 01:36:17 +000072 r = 13;
73 }
74 return r;
75}
76
Reid Kleckner9fe7f232015-07-07 00:36:30 +000077// 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*)
Reid Kleckner98cb8ba2015-07-07 22:26:07 +000080// X64: call void (...) @llvm.localescape(i32* %[[r:[^ ,]*]])
81// X86: call void (...) @llvm.localescape(i32* %[[r:[^ ,]*]], i32* %[[code:[^ ,]*]])
Reid Klecknere0bca752015-04-27 23:14:24 +000082// CHECK: store i32 42, i32* %[[r]]
Reid Klecknera5930002015-02-11 21:40:48 +000083// CHECK: invoke void @j() #[[NOINLINE]]
Reid Kleckner1d59f992015-01-22 01:36:17 +000084//
David Majnemer4e52d6f2015-12-12 05:39:21 +000085// CHECK: catchpad within %{{[^ ]*}} [i8* bitcast (i32 ({{.*}})* @"\01?filt$0@0@filter_expr_capture@@" to i8*)]
Reid Kleckner1d59f992015-01-22 01:36:17 +000086// CHECK: store i32 13, i32* %[[r]]
87//
David Blaikiea953f282015-02-27 21:19:58 +000088// CHECK: %[[rv:[^ ]*]] = load i32, i32* %[[r]]
Reid Kleckner1d59f992015-01-22 01:36:17 +000089// CHECK: ret i32 %[[rv]]
90
Reid Kleckner9fe7f232015-07-07 00:36:30 +000091// X64-LABEL: define internal i32 @"\01?filt$0@0@filter_expr_capture@@"(i8* %exception_pointers, i8* %frame_pointer)
Reid Kleckner39329d57b2015-12-16 00:26:37 +000092// 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)
Reid Kleckner9fe7f232015-07-07 00:36:30 +000094//
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]])
Reid Kleckner98cb8ba2015-07-07 22:26:07 +000098// X86: call i8* @llvm.localrecover(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %[[fp]], i32 0)
Reid Kleckner9fe7f232015-07-07 00:36:30 +000099//
Reid Klecknere0bca752015-04-27 23:14:24 +0000100// CHECK: store i32 -1, i32* %{{.*}}
Reid Kleckner1d59f992015-01-22 01:36:17 +0000101// CHECK: ret i32 -1
102
Reid Kleckner3a417c32015-01-30 22:16:45 +0000103int nested_try(void) {
Reid Kleckner1d59f992015-01-22 01:36:17 +0000104 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}
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000117// 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*)
Reid Kleckner1d59f992015-01-22 01:36:17 +0000120// CHECK: store i32 42, i32* %[[r:[^ ,]*]]
Reid Klecknera5930002015-02-11 21:40:48 +0000121// CHECK: invoke void @j() #[[NOINLINE]]
David Majnemer4e52d6f2015-12-12 05:39:21 +0000122// 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]]
Reid Kleckner1d59f992015-01-22 01:36:17 +0000141//
Reid Kleckner129552b2015-10-08 01:13:52 +0000142// CHECK: [[cpad_inner]]
David Majnemer4e52d6f2015-12-12 05:39:21 +0000143// CHECK: catchpad within %[[cs_inner]] [i8* bitcast (i32 ({{.*}})* @"\01?filt$1@0@nested_try@@" to i8*)]
144// CHECK-NEXT: catchret {{.*}} to label %[[except_inner:[^ ]*]]
Reid Kleckner129552b2015-10-08 01:13:52 +0000145//
146// CHECK: [[except_inner]]
147// CHECK: store i32 123, i32* %[[r]]
Reid Kleckner1d59f992015-01-22 01:36:17 +0000148// CHECK: br label %[[inner_try_cont:[^ ]*]]
149//
Reid Kleckner129552b2015-10-08 01:13:52 +0000150// CHECK: [[inner_try_cont]]
Reid Kleckner129552b2015-10-08 01:13:52 +0000151// CHECK: br label %[[outer_try_cont]]
152//
Reid Kleckner129552b2015-10-08 01:13:52 +0000153// CHECK: [[cont]]
154// CHECK: store i32 0, i32* %[[r]]
Reid Kleckner1d59f992015-01-22 01:36:17 +0000155// CHECK: br label %[[inner_try_cont]]
156//
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000157// 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
Reid Kleckner1d59f992015-01-22 01:36:17 +0000168
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000169int basic_finally(int g) {
Reid Kleckner1d59f992015-01-22 01:36:17 +0000170 __try {
171 j();
172 } __finally {
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000173 ++g;
Reid Kleckner1d59f992015-01-22 01:36:17 +0000174 }
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000175 return g;
Reid Kleckner1d59f992015-01-22 01:36:17 +0000176}
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000177// 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
Reid Kleckner98cb8ba2015-07-07 22:26:07 +0000181// CHECK: call void (...) @llvm.localescape(i32* %[[g_addr]])
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000182// CHECK: store i32 %g, i32* %[[g_addr]]
Reid Kleckner1d59f992015-01-22 01:36:17 +0000183//
184// CHECK: invoke void @j()
Reid Kleckner129552b2015-10-08 01:13:52 +0000185// CHECK: to label %[[cont:[^ ]*]] unwind label %[[cleanuppad:[^ ]*]]
Reid Kleckner1d59f992015-01-22 01:36:17 +0000186//
187// CHECK: [[cont]]
Reid Kleckner15d152d2015-07-07 23:23:31 +0000188// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000189// 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
Reid Kleckner1d59f992015-01-22 01:36:17 +0000192//
Reid Kleckner129552b2015-10-08 01:13:52 +0000193// CHECK: [[cleanuppad]]
David Majnemer4e52d6f2015-12-12 05:39:21 +0000194// CHECK: %[[padtoken:[^ ]*]] = cleanuppad within none []
Reid Kleckner15d152d2015-07-07 23:23:31 +0000195// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
David Majnemer4e52d6f2015-12-12 05:39:21 +0000196// CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
197// CHECK: cleanupret from %[[padtoken]] unwind to caller
Reid Kleckner3a417c32015-01-30 22:16:45 +0000198
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000199// CHECK: define internal void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} %abnormal_termination, i8* %frame_pointer)
Reid Kleckner98cb8ba2015-07-07 22:26:07 +0000200// CHECK: call i8* @llvm.localrecover(i8* bitcast (i32 (i32)* @basic_finally to i8*), i8* %frame_pointer, i32 0)
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000201// CHECK: load i32, i32* %{{.*}}, align 4
202// CHECK: add nsw i32 %{{.*}}, 1
203// CHECK: store i32 %{{.*}}, i32* %{{.*}}, align 4
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000204// CHECK: ret void
205
Reid Kleckner3a417c32015-01-30 22:16:45 +0000206int returns_int(void);
207int 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()
Reid Kleckner129552b2015-10-08 01:13:52 +0000216// CHECK: to label %[[cont:[^ ]*]] unwind label %[[catchpad:[^ ]*]]
Reid Kleckner3a417c32015-01-30 22:16:45 +0000217//
Reid Kleckner129552b2015-10-08 01:13:52 +0000218// CHECK: [[catchpad]]
219// CHECK: catchpad
220// CHECK: catchret
221// CHECK: store i32 42, i32* %[[rv:[^ ]*]]
Reid Kleckner3a417c32015-01-30 22:16:45 +0000222// CHECK: br label %[[retbb:[^ ]*]]
223//
Reid Kleckner129552b2015-10-08 01:13:52 +0000224// CHECK: [[cont]]
225// CHECK: store i32 %[[tmp]], i32* %[[rv]]
Reid Kleckner3a417c32015-01-30 22:16:45 +0000226// CHECK: br label %[[retbb]]
227//
228// CHECK: [[retbb]]
David Blaikiea953f282015-02-27 21:19:58 +0000229// CHECK: %[[r:[^ ]*]] = load i32, i32* %[[rv]]
Reid Kleckner3a417c32015-01-30 22:16:45 +0000230// CHECK: ret i32 %[[r]]
Reid Klecknera5930002015-02-11 21:40:48 +0000231
John McCall0a490152015-09-08 21:15:22 +0000232
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.
235void finally_capture_twice(int x) {
236 __try {
237 } __finally {
238 int y = x;
239 int z = x;
240 }
241}
Reid Klecknerbb34b602015-09-10 18:39:41 +0000242//
John McCall0a490152015-09-08 21:15:22 +0000243// 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
Reid Kleckner129552b2015-10-08 01:13:52 +0000262int 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
David Majnemer4e52d6f2015-12-12 05:39:21 +0000275// CHECK: catchret from %[[pad]]
Reid Kleckner129552b2015-10-08 01:13:52 +0000276// 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
Reid Klecknera5930002015-02-11 21:40:48 +0000283// CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} }