blob: de602fac416c04635f05b8488dbaa96853ca5e6d [file] [log] [blame]
Reid Klecknereb11c412015-07-01 21:00:00 +00001// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
Reid Kleckner9fe7f232015-07-07 00:36:30 +00002// FIXME: Re-enable 32-bit SEH.
3// RUNX: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
Reid Kleckner1d59f992015-01-22 01:36:17 +00004
Reid Kleckner16f9a6b2015-02-05 00:58:46 +00005void abort(void) __attribute__((noreturn));
Reid Kleckner1d59f992015-01-22 01:36:17 +00006void might_crash(void);
7void cleanup(void);
8int check_condition(void);
9void basic_finally(void) {
10 __try {
11 might_crash();
12 } __finally {
13 cleanup();
14 }
15}
16
17// CHECK-LABEL: define void @basic_finally()
18// CHECK: invoke void @might_crash()
Reid Kleckneraca01db2015-02-04 22:37:07 +000019// CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
20//
21// CHECK: [[invoke_cont]]
Reid Klecknereb11c412015-07-01 21:00:00 +000022// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
Reid Kleckner9fe7f232015-07-07 00:36:30 +000023// CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 0, i8* %[[fp]])
Reid Kleckneraca01db2015-02-04 22:37:07 +000024// CHECK-NEXT: ret void
25//
26// CHECK: [[lpad]]
27// CHECK-NEXT: landingpad
Reid Kleckner1d59f992015-01-22 01:36:17 +000028// CHECK-NEXT: cleanup
Reid Klecknereb11c412015-07-01 21:00:00 +000029// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
Reid Kleckner9fe7f232015-07-07 00:36:30 +000030// CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
Reid Kleckneraca01db2015-02-04 22:37:07 +000031// CHECK: resume { i8*, i32 }
Reid Kleckner1d59f992015-01-22 01:36:17 +000032
Reid Kleckner9fe7f232015-07-07 00:36:30 +000033// CHECK: define internal void @"\01?fin$0@0@basic_finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +000034// CHECK: call void @cleanup()
35
Reid Kleckneraca01db2015-02-04 22:37:07 +000036// Mostly check that we don't double emit 'r' which would crash.
37void decl_in_finally(void) {
38 __try {
39 might_crash();
40 } __finally {
41 int r;
42 }
43}
44
45// Ditto, don't crash double emitting 'l'.
46void label_in_finally(void) {
Reid Kleckner1d59f992015-01-22 01:36:17 +000047 __try {
48 might_crash();
49 } __finally {
50l:
51 cleanup();
52 if (check_condition())
53 goto l;
54 }
55}
Reid Kleckneraca01db2015-02-04 22:37:07 +000056
57// CHECK-LABEL: define void @label_in_finally()
58// CHECK: invoke void @might_crash()
59// CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
60//
61// CHECK: [[invoke_cont]]
Reid Klecknereb11c412015-07-01 21:00:00 +000062// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
Reid Kleckner9fe7f232015-07-07 00:36:30 +000063// CHECK: call void @"\01?fin$0@0@label_in_finally@@"({{i8( zeroext)?}} 0, i8* %[[fp]])
Reid Klecknerebaf28d2015-04-14 20:59:00 +000064// CHECK: ret void
65
Reid Kleckner9fe7f232015-07-07 00:36:30 +000066// CHECK: define internal void @"\01?fin$0@0@label_in_finally@@"({{.*}})
Reid Kleckneraca01db2015-02-04 22:37:07 +000067// CHECK: br label %[[l:[^ ]*]]
68//
69// CHECK: [[l]]
70// CHECK: call void @cleanup()
71// CHECK: call i32 @check_condition()
72// CHECK: br i1 {{.*}}, label
73// CHECK: br label %[[l]]
74
75int crashed;
76void use_abnormal_termination(void) {
77 __try {
78 might_crash();
79 } __finally {
80 crashed = __abnormal_termination();
81 }
82}
83
84// CHECK-LABEL: define void @use_abnormal_termination()
85// CHECK: invoke void @might_crash()
86// CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
87//
88// CHECK: [[invoke_cont]]
Reid Klecknereb11c412015-07-01 21:00:00 +000089// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
Reid Kleckner9fe7f232015-07-07 00:36:30 +000090// CHECK: call void @"\01?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} 0, i8* %[[fp]])
Reid Klecknerebaf28d2015-04-14 20:59:00 +000091// CHECK: ret void
Reid Kleckneraca01db2015-02-04 22:37:07 +000092//
93// CHECK: [[lpad]]
94// CHECK-NEXT: landingpad
95// CHECK-NEXT: cleanup
Reid Klecknereb11c412015-07-01 21:00:00 +000096// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
Reid Kleckner9fe7f232015-07-07 00:36:30 +000097// CHECK: call void @"\01?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
Reid Kleckneraca01db2015-02-04 22:37:07 +000098// CHECK: resume { i8*, i32 }
Reid Kleckner16f9a6b2015-02-05 00:58:46 +000099
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000100// CHECK: define internal void @"\01?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} %[[abnormal:abnormal_termination]], i8* %frame_pointer)
101// CHECK: %[[abnormal_zext:[^ ]*]] = zext i8 %[[abnormal]] to i32
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000102// CHECK: store i32 %[[abnormal_zext]], i32* @crashed
103// CHECK-NEXT: ret void
104
Reid Kleckner16f9a6b2015-02-05 00:58:46 +0000105void noreturn_noop_finally() {
106 __try {
107 __noop();
108 } __finally {
109 abort();
110 }
111}
112
113// CHECK-LABEL: define void @noreturn_noop_finally()
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000114// CHECK: call void @"\01?fin$0@0@noreturn_noop_finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000115// CHECK: ret void
116
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000117// CHECK: define internal void @"\01?fin$0@0@noreturn_noop_finally@@"({{.*}})
Reid Kleckner16f9a6b2015-02-05 00:58:46 +0000118// CHECK: call void @abort()
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000119// CHECK: unreachable
Reid Kleckner16f9a6b2015-02-05 00:58:46 +0000120
121void noreturn_finally() {
122 __try {
123 might_crash();
124 } __finally {
125 abort();
126 }
127}
128
129// CHECK-LABEL: define void @noreturn_finally()
130// CHECK: invoke void @might_crash()
131// CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
132//
133// CHECK: [[cont]]
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000134// CHECK: call void @"\01?fin$0@0@noreturn_finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000135// CHECK: ret void
Reid Kleckner16f9a6b2015-02-05 00:58:46 +0000136//
137// CHECK: [[lpad]]
138// CHECK: landingpad
139// CHECK-NEXT: cleanup
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000140// CHECK: call void @"\01?fin$0@0@noreturn_finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000141// CHECK: resume { i8*, i32 }
142
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000143// CHECK: define internal void @"\01?fin$0@0@noreturn_finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000144// CHECK: call void @abort()
145// CHECK: unreachable
Nico Webere68b9f32015-02-25 16:25:00 +0000146
147int finally_with_return() {
148 __try {
149 return 42;
150 } __finally {
151 }
152}
153// CHECK-LABEL: define i32 @finally_with_return()
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000154// CHECK: call void @"\01?fin$0@0@finally_with_return@@"({{.*}})
Nico Webere68b9f32015-02-25 16:25:00 +0000155// CHECK-NEXT: ret i32 42
156
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000157// CHECK: define internal void @"\01?fin$0@0@finally_with_return@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000158// CHECK-NOT: br i1
159// CHECK-NOT: br label
160// CHECK: ret void
161
Nico Webere68b9f32015-02-25 16:25:00 +0000162int nested___finally___finally() {
163 __try {
164 __try {
165 } __finally {
166 return 1;
167 }
168 } __finally {
169 // Intentionally no return here.
170 }
171 return 0;
172}
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000173
Nico Webere68b9f32015-02-25 16:25:00 +0000174// CHECK-LABEL: define i32 @nested___finally___finally
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000175// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000176// CHECK: to label %[[outercont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
Nico Webere68b9f32015-02-25 16:25:00 +0000177//
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000178// CHECK: [[outercont]]
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000179// CHECK: call void @"\01?fin$0@0@nested___finally___finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000180// CHECK-NEXT: ret i32 0
Nico Weberff62a6a2015-02-26 22:34:33 +0000181//
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000182// CHECK: [[lpad]]
183// CHECK-NEXT: landingpad
184// CHECK-NEXT: cleanup
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000185// CHECK: call void @"\01?fin$0@0@nested___finally___finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000186
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000187// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000188// CHECK: ret void
189
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000190// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000191// CHECK: unreachable
Nico Weberff62a6a2015-02-26 22:34:33 +0000192
193int nested___finally___finally_with_eh_edge() {
194 __try {
195 __try {
196 might_crash();
197 } __finally {
198 return 899;
199 }
200 } __finally {
201 // Intentionally no return here.
202 }
203 return 912;
204}
205// CHECK-LABEL: define i32 @nested___finally___finally_with_eh_edge
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000206// CHECK: invoke void @might_crash()
207// CHECK-NEXT: to label %[[invokecont:[^ ]*]] unwind label %[[lpad1:[^ ]*]]
Nico Weberff62a6a2015-02-26 22:34:33 +0000208//
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000209// [[invokecont]]
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000210// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000211// CHECK: to label %[[outercont:[^ ]*]] unwind label %[[lpad2:[^ ]*]]
Nico Weberff62a6a2015-02-26 22:34:33 +0000212//
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000213// CHECK: [[outercont]]
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000214// CHECK: call void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000215// CHECK-NEXT: ret i32 912
Nico Weberff62a6a2015-02-26 22:34:33 +0000216//
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000217// CHECK: [[lpad1]]
Nico Weberff62a6a2015-02-26 22:34:33 +0000218// CHECK-NEXT: landingpad
219// CHECK-NEXT: cleanup
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000220// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000221// CHECK: to label %[[outercont:[^ ]*]] unwind label %[[lpad2]]
Nico Weberff62a6a2015-02-26 22:34:33 +0000222//
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000223// CHECK: [[lpad2]]
224// CHECK-NEXT: landingpad
225// CHECK-NEXT: cleanup
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000226// CHECK: call void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}})
Nico Weberff62a6a2015-02-26 22:34:33 +0000227// CHECK: resume
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000228
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000229// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000230// CHECK: ret void
231
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000232// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000233// CHECK: unreachable