1 // RUN: %clang_cc1 -emit-llvm -o - %s -triple x86_64-linux | FileCheck %s
2
3 struct A {
4 A();
5 A(const A &);
6 ~A();
7 operator bool();
8 void *data;
9 };
10
11 A make();
12 bool cond();
13 void f(int);
14
15 // PR49585: Ensure that 'continue' performs the proper cleanups in the presence
16 // of a for loop condition variable.
17 //
18 // CHECK: define {{.*}} void @_Z7PR49585v(
PR49585()19 void PR49585() {
20 for (
21 // CHECK: call void @_Z1fi(i32 noundef 1)
22 // CHECK: br label %[[for_cond:.*]]
23 f(1);
24
25 // CHECK: [[for_cond]]:
26 // CHECK: call {{.*}} @_Z4makev(
27 // CHECK: call {{.*}} @_ZN1AcvbEv(
28 // CHECK: br i1 {{.*}}, label %[[for_body:.*]], label %[[for_cond_cleanup:.*]]
29 A a = make();
30
31 // CHECK: [[for_cond_cleanup]]:
32 // CHECK: store
33 // CHECK: br label %[[cleanup:.*]]
34
35 f(2)) {
36 // CHECK: [[for_body]]:
37 // CHECK: call {{.*}} @_Z4condv(
38 // CHECK: br i1 {{.*}}, label %[[if_then:.*]], label %[[if_end:.*]]
39 if (cond()) {
40 // CHECK: [[if_then]]:
41 // CHECK: call {{.*}} @_Z1fi(i32 noundef 3)
42 // CHECK: br label %[[for_inc:.*]]
43 f(3);
44 continue;
45 }
46
47 // CHECK: [[if_end]]:
48 // CHECK: call {{.*}} @_Z1fi(i32 noundef 4)
49 // CHECK: br label %[[for_inc]]
50 f(4);
51 }
52
53 // CHECK: [[for_inc]]:
54 // CHECK: call void @_Z1fi(i32 noundef 2)
55 // CHECK: store
56 // CHECK: br label %[[cleanup]]
57
58 // CHECK: [[cleanup]]:
59 // CHECK: call void @_ZN1AD1Ev(
60 // CHECK: load
61 // CHECK: switch {{.*}} label
62 // CHECK-NEXT: label %[[cleanup_cont:.*]]
63 // CHECK-NEXT: label %[[for_end:.*]]
64
65 // CHECK: [[cleanup_cont]]:
66 // CHECK: br label %[[for_cond]]
67
68 // CHECK [[for_end]]:
69 // CHECK: ret void
70 }
71
72 // CHECK: define {{.*}} void @_Z13PR49585_breakv(
PR49585_break()73 void PR49585_break() {
74 for (
75 // CHECK: call void @_Z1fi(i32 noundef 1)
76 // CHECK: br label %[[for_cond:.*]]
77 f(1);
78
79 // CHECK: [[for_cond]]:
80 // CHECK: call {{.*}} @_Z4makev(
81 // CHECK: call {{.*}} @_ZN1AcvbEv(
82 // CHECK: br i1 {{.*}}, label %[[for_body:.*]], label %[[for_cond_cleanup:.*]]
83 A a = make();
84
85 // CHECK: [[for_cond_cleanup]]:
86 // CHECK: store
87 // CHECK: br label %[[cleanup:.*]]
88
89 f(2)) {
90 // CHECK: [[for_body]]:
91 // CHECK: call {{.*}} @_Z4condv(
92 // CHECK: br i1 {{.*}}, label %[[if_then:.*]], label %[[if_end:.*]]
93 if (cond()) {
94 // CHECK: [[if_then]]:
95 // CHECK: call {{.*}} @_Z1fi(i32 noundef 3)
96 // CHECK: store
97 // CHECK: br label %[[cleanup:.*]]
98 f(3);
99 break;
100 }
101
102 // CHECK: [[if_end]]:
103 // CHECK: call {{.*}} @_Z1fi(i32 noundef 4)
104 // CHECK: br label %[[for_inc]]
105 f(4);
106 }
107
108 // CHECK: [[for_inc]]:
109 // CHECK: call void @_Z1fi(i32 noundef 2)
110 // CHECK: store
111 // CHECK: br label %[[cleanup]]
112
113 // CHECK: [[cleanup]]:
114 // CHECK: call void @_ZN1AD1Ev(
115 // CHECK: load
116 // CHECK: switch {{.*}} label
117 // CHECK-NEXT: label %[[cleanup_cont:.*]]
118 // CHECK-NEXT: label %[[for_end:.*]]
119
120 // CHECK: [[cleanup_cont]]:
121 // CHECK: br label %[[for_cond]]
122
123 // CHECK [[for_end]]:
124 // CHECK: ret void
125 }
126
127 // CHECK: define {{.*}} void @_Z16incless_for_loopv(
incless_for_loop()128 void incless_for_loop() {
129 // CHECK: br label %[[for_cond:.*]]
130 // CHECK: [[for_cond]]:
131 // CHECK: br i1 {{.*}}, label %[[for_body:.*]], label %[[for_end:.*]]
132 // CHECK: [[for_body]]:
133 // CHECK: br label %[[for_cond]]
134 // CHECK: [[for_end]]:
135 // CHECK: ret void
136 // CHECK: }
137 for (; int b = 0;) continue;
138 }
139