1 // 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
3 // RUN: %clang_cc1 %s -triple aarch64-windows -fms-extensions -emit-llvm -o - | FileCheck %s
4 
5 void abort(void) __attribute__((noreturn));
6 void might_crash(void);
7 void cleanup(void);
8 int check_condition(void);
9 void basic_finally(void) {
10   __try {
11     might_crash();
12   } __finally {
13     cleanup();
14   }
15 }
16 
17 // CHECK-LABEL: define dso_local void @basic_finally()
18 // CHECK: invoke void @might_crash()
19 // CHECK:     to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
20 //
21 // CHECK: [[invoke_cont]]
22 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
23 // CHECK: call void @"?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 0, i8* %[[fp]])
24 // CHECK-NEXT: ret void
25 //
26 // CHECK: [[lpad]]
27 // CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad
28 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
29 // CHECK: call void @"?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
30 // CHECK-NEXT: cleanupret from %[[pad]] unwind to caller
31 
32 // CHECK: define internal void @"?fin$0@0@basic_finally@@"({{.*}})
33 // CHECK-SAME: [[finally_attrs:#[0-9]+]]
34 // CHECK: call void @cleanup()
35 
36 // Mostly check that we don't double emit 'r' which would crash.
37 void 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'.
46 void label_in_finally(void) {
47   __try {
48     might_crash();
49   } __finally {
50 l:
51     cleanup();
52     if (check_condition())
53       goto l;
54   }
55 }
56 
57 // CHECK-LABEL: define dso_local void @label_in_finally()
58 // CHECK: invoke void @might_crash()
59 // CHECK:     to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
60 //
61 // CHECK: [[invoke_cont]]
62 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
63 // CHECK: call void @"?fin$0@0@label_in_finally@@"({{i8( zeroext)?}} 0, i8* %[[fp]])
64 // CHECK: ret void
65 
66 // CHECK: define internal void @"?fin$0@0@label_in_finally@@"({{.*}})
67 // CHECK-SAME: [[finally_attrs]]
68 // CHECK: br label %[[l:[^ ]*]]
69 //
70 // CHECK: [[l]]
71 // CHECK: call void @cleanup()
72 // CHECK: call i32 @check_condition()
73 // CHECK: br i1 {{.*}}, label
74 // CHECK: br label %[[l]]
75 
76 int crashed;
77 void use_abnormal_termination(void) {
78   __try {
79     might_crash();
80   } __finally {
81     crashed = __abnormal_termination();
82   }
83 }
84 
85 // CHECK-LABEL: define dso_local void @use_abnormal_termination()
86 // CHECK: invoke void @might_crash()
87 // CHECK:     to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
88 //
89 // CHECK: [[invoke_cont]]
90 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
91 // CHECK: call void @"?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} 0, i8* %[[fp]])
92 // CHECK: ret void
93 //
94 // CHECK: [[lpad]]
95 // CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad
96 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
97 // CHECK: call void @"?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
98 // CHECK-NEXT: cleanupret from %[[pad]] unwind to caller
99 
100 // CHECK: define internal void @"?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} %[[abnormal:abnormal_termination]], i8* %frame_pointer)
101 // CHECK-SAME: [[finally_attrs]]
102 // CHECK: %[[abnormal_zext:[^ ]*]] = zext i8 %[[abnormal]] to i32
103 // CHECK: store i32 %[[abnormal_zext]], i32* @crashed
104 // CHECK-NEXT: ret void
105 
106 void noreturn_noop_finally() {
107   __try {
108     __noop();
109   } __finally {
110     abort();
111   }
112 }
113 
114 // CHECK-LABEL: define dso_local void @noreturn_noop_finally()
115 // CHECK: call void @"?fin$0@0@noreturn_noop_finally@@"({{.*}})
116 // CHECK: ret void
117 
118 // CHECK: define internal void @"?fin$0@0@noreturn_noop_finally@@"({{.*}})
119 // CHECK-SAME: [[finally_attrs]]
120 // CHECK: call void @abort()
121 // CHECK: unreachable
122 
123 void noreturn_finally() {
124   __try {
125     might_crash();
126   } __finally {
127     abort();
128   }
129 }
130 
131 // CHECK-LABEL: define dso_local void @noreturn_finally()
132 // CHECK: invoke void @might_crash()
133 // CHECK:     to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
134 //
135 // CHECK: [[cont]]
136 // CHECK: call void @"?fin$0@0@noreturn_finally@@"({{.*}})
137 // CHECK: ret void
138 //
139 // CHECK: [[lpad]]
140 // CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad
141 // CHECK: call void @"?fin$0@0@noreturn_finally@@"({{.*}})
142 // CHECK-NEXT: cleanupret from %[[pad]] unwind to caller
143 
144 // CHECK: define internal void @"?fin$0@0@noreturn_finally@@"({{.*}})
145 // CHECK-SAME: [[finally_attrs]]
146 // CHECK: call void @abort()
147 // CHECK: unreachable
148 
149 int finally_with_return() {
150   __try {
151     return 42;
152   } __finally {
153   }
154 }
155 // CHECK-LABEL: define dso_local i32 @finally_with_return()
156 // CHECK: call void @"?fin$0@0@finally_with_return@@"({{.*}})
157 // CHECK-NEXT: ret i32 42
158 
159 // CHECK: define internal void @"?fin$0@0@finally_with_return@@"({{.*}})
160 // CHECK-SAME: [[finally_attrs]]
161 // CHECK-NOT: br i1
162 // CHECK-NOT: br label
163 // CHECK: ret void
164 
165 int nested___finally___finally() {
166   __try {
167     __try {
168     } __finally {
169       return 1;
170     }
171   } __finally {
172     // Intentionally no return here.
173   }
174   return 0;
175 }
176 
177 // CHECK-LABEL: define dso_local i32 @nested___finally___finally
178 // CHECK: invoke void @"?fin$1@0@nested___finally___finally@@"({{.*}})
179 // CHECK:          to label %[[outercont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
180 //
181 // CHECK: [[outercont]]
182 // CHECK: call void @"?fin$0@0@nested___finally___finally@@"({{.*}})
183 // CHECK-NEXT: ret i32 0
184 //
185 // CHECK: [[lpad]]
186 // CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad
187 // CHECK: call void @"?fin$0@0@nested___finally___finally@@"({{.*}})
188 // CHECK-NEXT: cleanupret from %[[pad]] unwind to caller
189 
190 // CHECK-LABEL: define internal void @"?fin$0@0@nested___finally___finally@@"({{.*}})
191 // CHECK-SAME: [[finally_attrs]]
192 // CHECK: ret void
193 
194 // CHECK-LABEL: define internal void @"?fin$1@0@nested___finally___finally@@"({{.*}})
195 // CHECK-SAME: [[finally_attrs]]
196 // CHECK: unreachable
197 
198 // FIXME: Our behavior seems suspiciously different.
199 
200 int nested___finally___finally_with_eh_edge() {
201   __try {
202     __try {
203       might_crash();
204     } __finally {
205       return 899;
206     }
207   } __finally {
208     // Intentionally no return here.
209   }
210   return 912;
211 }
212 // CHECK-LABEL: define dso_local i32 @nested___finally___finally_with_eh_edge
213 // CHECK: invoke void @might_crash()
214 // CHECK-NEXT: to label %[[invokecont:[^ ]*]] unwind label %[[lpad1:[^ ]*]]
215 //
216 // [[invokecont]]
217 // CHECK: invoke void @"?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})
218 // CHECK-NEXT:       to label %[[outercont:[^ ]*]] unwind label %[[lpad2:[^ ]*]]
219 //
220 // CHECK: [[outercont]]
221 // CHECK: call void @"?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}})
222 // CHECK-NEXT: ret i32 912
223 //
224 // CHECK: [[lpad1]]
225 // CHECK-NEXT: %[[innerpad:[^ ]*]] = cleanuppad
226 // CHECK: invoke void @"?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})
227 // CHECK-NEXT:    label %[[innercleanupretbb:[^ ]*]] unwind label %[[lpad2:[^ ]*]]
228 //
229 // CHECK: [[innercleanupretbb]]
230 // CHECK-NEXT: cleanupret from %[[innerpad]] unwind label %[[lpad2]]
231 //
232 // CHECK: [[lpad2]]
233 // CHECK-NEXT: %[[outerpad:[^ ]*]] = cleanuppad
234 // CHECK: call void @"?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}})
235 // CHECK-NEXT: cleanupret from %[[outerpad]] unwind to caller
236 
237 // CHECK-LABEL: define internal void @"?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}})
238 // CHECK-SAME: [[finally_attrs]]
239 // CHECK: ret void
240 
241 // CHECK-LABEL: define internal void @"?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})
242 // CHECK-SAME: [[finally_attrs]]
243 // CHECK: unreachable
244 
245 void finally_within_finally() {
246   __try {
247     might_crash();
248   } __finally {
249     __try {
250       might_crash();
251     } __finally {
252     }
253   }
254 }
255 
256 // CHECK-LABEL: define dso_local void @finally_within_finally(
257 // CHECK: invoke void @might_crash(
258 
259 // CHECK: call void @"?fin$0@0@finally_within_finally@@"(
260 // CHECK: call void @"?fin$0@0@finally_within_finally@@"({{.*}}) [ "funclet"(
261 
262 // CHECK-LABEL: define internal void @"?fin$0@0@finally_within_finally@@"({{[^)]*}})
263 // CHECK-SAME: [[finally_attrs]]
264 // CHECK: invoke void @might_crash(
265 
266 // CHECK: call void @"?fin$1@0@finally_within_finally@@"(
267 // CHECK: call void @"?fin$1@0@finally_within_finally@@"({{.*}}) [ "funclet"(
268 
269 // CHECK-LABEL: define internal void @"?fin$1@0@finally_within_finally@@"({{[^)]*}})
270 // CHECK-SAME: [[finally_attrs]]
271 
272 void cleanup_with_func(const char *);
273 void finally_with_func() {
274   __try {
275     might_crash();
276   } __finally {
277     cleanup_with_func(__func__);
278   }
279 }
280 
281 // CHECK-LABEL: define internal void @"?fin$0@0@finally_with_func@@"({{[^)]*}})
282 // CHECK: call void @cleanup_with_func(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @"??_C@_0BC@COAGBPGM@finally_with_func?$AA@", i{{32|64}} 0, i{{32|64}} 0))
283 
284 // Look for the absence of noinline. Enum attributes come first, so check that
285 // a string attribute is the first to verify that no enum attributes are
286 // present.
287 // CHECK: attributes [[finally_attrs]] = { "{{.*}}" }
288