blob: d7653dda9126b22c3d53612555a34dea28815c1f [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
2// 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 Klecknereb11c412015-07-01 21:00:00 +000021// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
22// 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]]
26// CHECK-NEXT: landingpad
Reid Kleckner1d59f992015-01-22 01:36:17 +000027// CHECK-NEXT: cleanup
Reid Klecknereb11c412015-07-01 21:00:00 +000028// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
29// CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
Reid Kleckneraca01db2015-02-04 22:37:07 +000030// CHECK: resume { i8*, i32 }
Reid Kleckner1d59f992015-01-22 01:36:17 +000031
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +000032// CHECK: define internal void @"\01?fin$0@0@basic_finally@@"({{.*}})
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 Klecknereb11c412015-07-01 21:00:00 +000061// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
62// 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 Klecknerd0d9a1f2015-07-01 17:10:10 +000065// CHECK: define internal void @"\01?fin$0@0@label_in_finally@@"({{.*}})
Reid Kleckneraca01db2015-02-04 22:37:07 +000066// CHECK: br label %[[l:[^ ]*]]
67//
68// CHECK: [[l]]
69// CHECK: call void @cleanup()
70// CHECK: call i32 @check_condition()
71// CHECK: br i1 {{.*}}, label
72// CHECK: br label %[[l]]
73
74int crashed;
75void use_abnormal_termination(void) {
76 __try {
77 might_crash();
78 } __finally {
79 crashed = __abnormal_termination();
80 }
81}
82
83// CHECK-LABEL: define void @use_abnormal_termination()
84// CHECK: invoke void @might_crash()
85// CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
86//
87// CHECK: [[invoke_cont]]
Reid Klecknereb11c412015-07-01 21:00:00 +000088// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
89// CHECK: call void @"\01?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} 0, i8* %[[fp]])
Reid Klecknerebaf28d2015-04-14 20:59:00 +000090// CHECK: ret void
Reid Kleckneraca01db2015-02-04 22:37:07 +000091//
92// CHECK: [[lpad]]
93// CHECK-NEXT: landingpad
94// CHECK-NEXT: cleanup
Reid Klecknereb11c412015-07-01 21:00:00 +000095// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
96// CHECK: call void @"\01?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
Reid Kleckneraca01db2015-02-04 22:37:07 +000097// CHECK: resume { i8*, i32 }
Reid Kleckner16f9a6b2015-02-05 00:58:46 +000098
Reid Klecknereb11c412015-07-01 21:00:00 +000099// CHECK: define internal void @"\01?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} %[[abnormal:abnormal_termination]], i8* %frame_pointer)
100// CHECK: %[[abnormal_zext:[^ ]*]] = zext i8 %[[abnormal]] to i32
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000101// CHECK: store i32 %[[abnormal_zext]], i32* @crashed
102// CHECK-NEXT: ret void
103
Reid Kleckner16f9a6b2015-02-05 00:58:46 +0000104void noreturn_noop_finally() {
105 __try {
106 __noop();
107 } __finally {
108 abort();
109 }
110}
111
112// CHECK-LABEL: define void @noreturn_noop_finally()
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +0000113// CHECK: call void @"\01?fin$0@0@noreturn_noop_finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000114// CHECK: ret void
115
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +0000116// CHECK: define internal void @"\01?fin$0@0@noreturn_noop_finally@@"({{.*}})
Reid Kleckner16f9a6b2015-02-05 00:58:46 +0000117// CHECK: call void @abort()
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000118// CHECK: unreachable
Reid Kleckner16f9a6b2015-02-05 00:58:46 +0000119
120void noreturn_finally() {
121 __try {
122 might_crash();
123 } __finally {
124 abort();
125 }
126}
127
128// CHECK-LABEL: define void @noreturn_finally()
129// CHECK: invoke void @might_crash()
130// CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
131//
132// CHECK: [[cont]]
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +0000133// CHECK: call void @"\01?fin$0@0@noreturn_finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000134// CHECK: ret void
Reid Kleckner16f9a6b2015-02-05 00:58:46 +0000135//
136// CHECK: [[lpad]]
137// CHECK: landingpad
138// CHECK-NEXT: cleanup
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +0000139// CHECK: call void @"\01?fin$0@0@noreturn_finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000140// CHECK: resume { i8*, i32 }
141
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +0000142// CHECK: define internal void @"\01?fin$0@0@noreturn_finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000143// CHECK: call void @abort()
144// CHECK: unreachable
Nico Webere68b9f32015-02-25 16:25:00 +0000145
146int finally_with_return() {
147 __try {
148 return 42;
149 } __finally {
150 }
151}
152// CHECK-LABEL: define i32 @finally_with_return()
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +0000153// CHECK: call void @"\01?fin$0@0@finally_with_return@@"({{.*}})
Nico Webere68b9f32015-02-25 16:25:00 +0000154// CHECK-NEXT: ret i32 42
155
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +0000156// CHECK: define internal void @"\01?fin$0@0@finally_with_return@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000157// CHECK-NOT: br i1
158// CHECK-NOT: br label
159// CHECK: ret void
160
Nico Webere68b9f32015-02-25 16:25:00 +0000161int nested___finally___finally() {
162 __try {
163 __try {
164 } __finally {
165 return 1;
166 }
167 } __finally {
168 // Intentionally no return here.
169 }
170 return 0;
171}
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000172
Nico Webere68b9f32015-02-25 16:25:00 +0000173// CHECK-LABEL: define i32 @nested___finally___finally
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +0000174// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000175// CHECK: to label %[[outercont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
Nico Webere68b9f32015-02-25 16:25:00 +0000176//
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000177// CHECK: [[outercont]]
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +0000178// CHECK: call void @"\01?fin$0@0@nested___finally___finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000179// CHECK-NEXT: ret i32 0
Nico Weberff62a6a2015-02-26 22:34:33 +0000180//
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000181// CHECK: [[lpad]]
182// CHECK-NEXT: landingpad
183// CHECK-NEXT: cleanup
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +0000184// CHECK: call void @"\01?fin$0@0@nested___finally___finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000185
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +0000186// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000187// CHECK: ret void
188
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +0000189// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000190// CHECK: unreachable
Nico Weberff62a6a2015-02-26 22:34:33 +0000191
192int nested___finally___finally_with_eh_edge() {
193 __try {
194 __try {
195 might_crash();
196 } __finally {
197 return 899;
198 }
199 } __finally {
200 // Intentionally no return here.
201 }
202 return 912;
203}
204// CHECK-LABEL: define i32 @nested___finally___finally_with_eh_edge
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000205// CHECK: invoke void @might_crash()
206// CHECK-NEXT: to label %[[invokecont:[^ ]*]] unwind label %[[lpad1:[^ ]*]]
Nico Weberff62a6a2015-02-26 22:34:33 +0000207//
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000208// [[invokecont]]
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +0000209// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000210// CHECK: to label %[[outercont:[^ ]*]] unwind label %[[lpad2:[^ ]*]]
Nico Weberff62a6a2015-02-26 22:34:33 +0000211//
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000212// CHECK: [[outercont]]
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +0000213// CHECK: call void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000214// CHECK-NEXT: ret i32 912
Nico Weberff62a6a2015-02-26 22:34:33 +0000215//
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000216// CHECK: [[lpad1]]
Nico Weberff62a6a2015-02-26 22:34:33 +0000217// CHECK-NEXT: landingpad
218// CHECK-NEXT: cleanup
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +0000219// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000220// CHECK: to label %[[outercont:[^ ]*]] unwind label %[[lpad2]]
Nico Weberff62a6a2015-02-26 22:34:33 +0000221//
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000222// CHECK: [[lpad2]]
223// CHECK-NEXT: landingpad
224// CHECK-NEXT: cleanup
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +0000225// CHECK: call void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}})
Nico Weberff62a6a2015-02-26 22:34:33 +0000226// CHECK: resume
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000227
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +0000228// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000229// CHECK: ret void
230
Reid Klecknerd0d9a1f2015-07-01 17:10:10 +0000231// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})
Reid Klecknerebaf28d2015-04-14 20:59:00 +0000232// CHECK: unreachable