blob: 0f2123ba32bb35a8e1957b4d0cbadd50f9d88c76 [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 Kleckner8819a402015-07-10 00:16:25 +00002// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
Reid Kleckner1d59f992015-01-22 01:36:17 +00003
Reid Kleckner16f9a6b2015-02-05 00:58:46 +00004void abort(void) __attribute__((noreturn));
Reid Kleckner1d59f992015-01-22 01:36:17 +00005void might_crash(void);
6void cleanup(void);
7int check_condition(void);
8void basic_finally(void) {
9 __try {
10 might_crash();
11 } __finally {
12 cleanup();
13 }
14}
15
16// CHECK-LABEL: define void @basic_finally()
17// CHECK: invoke void @might_crash()
Reid Kleckneraca01db2015-02-04 22:37:07 +000018// CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
19//
20// CHECK: [[invoke_cont]]
Reid Kleckner15d152d2015-07-07 23:23:31 +000021// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
Reid Kleckner9fe7f232015-07-07 00:36:30 +000022// CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 0, i8* %[[fp]])
Reid Kleckneraca01db2015-02-04 22:37:07 +000023// CHECK-NEXT: ret void
24//
25// CHECK: [[lpad]]
Reid Kleckner129552b2015-10-08 01:13:52 +000026// CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad
Reid Kleckner15d152d2015-07-07 23:23:31 +000027// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
David Majnemer4e52d6f2015-12-12 05:39:21 +000028// CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
29// CHECK-NEXT: cleanupret from %[[pad]] unwind to caller
Reid Kleckner1d59f992015-01-22 01:36:17 +000030
Reid Kleckner9fe7f232015-07-07 00:36:30 +000031// CHECK: define internal void @"\01?fin$0@0@basic_finally@@"({{.*}})
Reid Klecknere10b6012016-03-11 17:36:16 +000032// CHECK-SAME: [[finally_attrs:#[0-9]+]]
Reid Klecknerebaf28d2015-04-14 20:59:00 +000033// CHECK: call void @cleanup()
34
Reid Kleckneraca01db2015-02-04 22:37:07 +000035// Mostly check that we don't double emit 'r' which would crash.
36void decl_in_finally(void) {
37 __try {
38 might_crash();
39 } __finally {
40 int r;
41 }
42}
43
44// Ditto, don't crash double emitting 'l'.
45void label_in_finally(void) {
Reid Kleckner1d59f992015-01-22 01:36:17 +000046 __try {
47 might_crash();
48 } __finally {
49l:
50 cleanup();
51 if (check_condition())
52 goto l;
53 }
54}
Reid Kleckneraca01db2015-02-04 22:37:07 +000055
56// CHECK-LABEL: define void @label_in_finally()
57// CHECK: invoke void @might_crash()
58// CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
59//
60// CHECK: [[invoke_cont]]
Reid Kleckner15d152d2015-07-07 23:23:31 +000061// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
Reid Kleckner9fe7f232015-07-07 00:36:30 +000062// CHECK: call void @"\01?fin$0@0@label_in_finally@@"({{i8( zeroext)?}} 0, i8* %[[fp]])
Reid Klecknerebaf28d2015-04-14 20:59:00 +000063// CHECK: ret void
64
Reid Kleckner9fe7f232015-07-07 00:36:30 +000065// CHECK: define internal void @"\01?fin$0@0@label_in_finally@@"({{.*}})
Reid Klecknere10b6012016-03-11 17:36:16 +000066// CHECK-SAME: [[finally_attrs]]
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 Kleckner15d152d2015-07-07 23:23:31 +000089// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
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]]
Reid Kleckner129552b2015-10-08 01:13:52 +000094// CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad
Reid Kleckner15d152d2015-07-07 23:23:31 +000095// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
David Majnemer4e52d6f2015-12-12 05:39:21 +000096// CHECK: call void @"\01?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
97// CHECK-NEXT: cleanupret from %[[pad]] unwind to caller
Reid Kleckner16f9a6b2015-02-05 00:58:46 +000098
Reid Kleckner9fe7f232015-07-07 00:36:30 +000099// CHECK: define internal void @"\01?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} %[[abnormal:abnormal_termination]], i8* %frame_pointer)
Reid Klecknere10b6012016-03-11 17:36:16 +0000100// CHECK-SAME: [[finally_attrs]]
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000101// 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 Klecknere10b6012016-03-11 17:36:16 +0000118// CHECK-SAME: [[finally_attrs]]
Reid Kleckner16f9a6b2015-02-05 00:58:46 +0000119// CHECK: call void @abort()
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000120// CHECK: unreachable
Reid Kleckner16f9a6b2015-02-05 00:58:46 +0000121
122void noreturn_finally() {
123 __try {
124 might_crash();
125 } __finally {
126 abort();
127 }
128}
129
130// CHECK-LABEL: define void @noreturn_finally()
131// CHECK: invoke void @might_crash()
132// CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
133//
134// CHECK: [[cont]]
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000135// CHECK: call void @"\01?fin$0@0@noreturn_finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000136// CHECK: ret void
Reid Kleckner16f9a6b2015-02-05 00:58:46 +0000137//
138// CHECK: [[lpad]]
Reid Kleckner129552b2015-10-08 01:13:52 +0000139// CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad
David Majnemer4e52d6f2015-12-12 05:39:21 +0000140// CHECK: call void @"\01?fin$0@0@noreturn_finally@@"({{.*}})
141// CHECK-NEXT: cleanupret from %[[pad]] unwind to caller
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000142
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000143// CHECK: define internal void @"\01?fin$0@0@noreturn_finally@@"({{.*}})
Reid Klecknere10b6012016-03-11 17:36:16 +0000144// CHECK-SAME: [[finally_attrs]]
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000145// CHECK: call void @abort()
146// CHECK: unreachable
Nico Webere68b9f32015-02-25 16:25:00 +0000147
148int finally_with_return() {
149 __try {
150 return 42;
151 } __finally {
152 }
153}
154// CHECK-LABEL: define i32 @finally_with_return()
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000155// CHECK: call void @"\01?fin$0@0@finally_with_return@@"({{.*}})
Nico Webere68b9f32015-02-25 16:25:00 +0000156// CHECK-NEXT: ret i32 42
157
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000158// CHECK: define internal void @"\01?fin$0@0@finally_with_return@@"({{.*}})
Reid Klecknere10b6012016-03-11 17:36:16 +0000159// CHECK-SAME: [[finally_attrs]]
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000160// CHECK-NOT: br i1
161// CHECK-NOT: br label
162// CHECK: ret void
163
Nico Webere68b9f32015-02-25 16:25:00 +0000164int nested___finally___finally() {
165 __try {
166 __try {
167 } __finally {
168 return 1;
169 }
170 } __finally {
171 // Intentionally no return here.
172 }
173 return 0;
174}
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000175
Nico Webere68b9f32015-02-25 16:25:00 +0000176// CHECK-LABEL: define i32 @nested___finally___finally
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000177// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000178// CHECK: to label %[[outercont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
Nico Webere68b9f32015-02-25 16:25:00 +0000179//
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000180// CHECK: [[outercont]]
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000181// CHECK: call void @"\01?fin$0@0@nested___finally___finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000182// CHECK-NEXT: ret i32 0
Nico Weberff62a6a2015-02-26 22:34:33 +0000183//
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000184// CHECK: [[lpad]]
Reid Kleckner129552b2015-10-08 01:13:52 +0000185// CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad
David Majnemer4e52d6f2015-12-12 05:39:21 +0000186// CHECK: call void @"\01?fin$0@0@nested___finally___finally@@"({{.*}})
187// CHECK-NEXT: cleanupret from %[[pad]] unwind to caller
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000188
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000189// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally@@"({{.*}})
Reid Klecknere10b6012016-03-11 17:36:16 +0000190// CHECK-SAME: [[finally_attrs]]
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000191// CHECK: ret void
192
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000193// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally@@"({{.*}})
Reid Klecknere10b6012016-03-11 17:36:16 +0000194// CHECK-SAME: [[finally_attrs]]
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000195// CHECK: unreachable
Nico Weberff62a6a2015-02-26 22:34:33 +0000196
Reid Kleckner129552b2015-10-08 01:13:52 +0000197// FIXME: Our behavior seems suspiciously different.
198
Nico Weberff62a6a2015-02-26 22:34:33 +0000199int nested___finally___finally_with_eh_edge() {
200 __try {
201 __try {
202 might_crash();
203 } __finally {
204 return 899;
205 }
206 } __finally {
207 // Intentionally no return here.
208 }
209 return 912;
210}
211// CHECK-LABEL: define i32 @nested___finally___finally_with_eh_edge
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000212// CHECK: invoke void @might_crash()
213// CHECK-NEXT: to label %[[invokecont:[^ ]*]] unwind label %[[lpad1:[^ ]*]]
Nico Weberff62a6a2015-02-26 22:34:33 +0000214//
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000215// [[invokecont]]
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000216// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})
Reid Kleckner129552b2015-10-08 01:13:52 +0000217// CHECK-NEXT: to label %[[outercont:[^ ]*]] unwind label %[[lpad2:[^ ]*]]
Nico Weberff62a6a2015-02-26 22:34:33 +0000218//
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000219// CHECK: [[outercont]]
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000220// CHECK: call void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000221// CHECK-NEXT: ret i32 912
Nico Weberff62a6a2015-02-26 22:34:33 +0000222//
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000223// CHECK: [[lpad1]]
Reid Kleckner129552b2015-10-08 01:13:52 +0000224// CHECK-NEXT: %[[innerpad:[^ ]*]] = cleanuppad
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000225// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})
David Majnemer4e52d6f2015-12-12 05:39:21 +0000226// CHECK-NEXT: label %[[innercleanupretbb:[^ ]*]] unwind label %[[lpad2:[^ ]*]]
Reid Kleckner129552b2015-10-08 01:13:52 +0000227//
228// CHECK: [[innercleanupretbb]]
David Majnemer4e52d6f2015-12-12 05:39:21 +0000229// CHECK-NEXT: cleanupret from %[[innerpad]] unwind label %[[lpad2]]
Nico Weberff62a6a2015-02-26 22:34:33 +0000230//
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000231// CHECK: [[lpad2]]
Reid Kleckner129552b2015-10-08 01:13:52 +0000232// CHECK-NEXT: %[[outerpad:[^ ]*]] = cleanuppad
David Majnemer4e52d6f2015-12-12 05:39:21 +0000233// CHECK: call void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}})
234// CHECK-NEXT: cleanupret from %[[outerpad]] unwind to caller
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000235
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000236// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}})
Reid Klecknere10b6012016-03-11 17:36:16 +0000237// CHECK-SAME: [[finally_attrs]]
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000238// CHECK: ret void
239
Reid Kleckner9fe7f232015-07-07 00:36:30 +0000240// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})
Reid Klecknere10b6012016-03-11 17:36:16 +0000241// CHECK-SAME: [[finally_attrs]]
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000242// CHECK: unreachable
David Majnemer25eb1652016-03-01 19:42:53 +0000243
244void finally_within_finally() {
245 __try {
246 might_crash();
247 } __finally {
248 __try {
249 might_crash();
250 } __finally {
251 }
252 }
253}
254
255// CHECK-LABEL: define void @finally_within_finally(
256// CHECK: invoke void @might_crash(
257
258// CHECK: call void @"\01?fin$0@0@finally_within_finally@@"(
259// CHECK: call void @"\01?fin$0@0@finally_within_finally@@"({{.*}}) [ "funclet"(
260
Reid Klecknere10b6012016-03-11 17:36:16 +0000261// CHECK-LABEL: define internal void @"\01?fin$0@0@finally_within_finally@@"({{[^)]*}})
262// CHECK-SAME: [[finally_attrs]]
David Majnemer25eb1652016-03-01 19:42:53 +0000263// CHECK: invoke void @might_crash(
264
265// CHECK: call void @"\01?fin$1@0@finally_within_finally@@"(
266// CHECK: call void @"\01?fin$1@0@finally_within_finally@@"({{.*}}) [ "funclet"(
267
Reid Klecknere10b6012016-03-11 17:36:16 +0000268// CHECK-LABEL: define internal void @"\01?fin$1@0@finally_within_finally@@"({{[^)]*}})
269// CHECK-SAME: [[finally_attrs]]
270
271// Look for the absence of noinline. Enum attributes come first, so check that
272// a string attribute is the first to verify that no enum attributes are
273// present.
274// CHECK: attributes [[finally_attrs]] = { "{{.*}}" }