xref: /llvm-project/clang/test/CodeGenCXX/for-cond-var.cpp (revision 1b1c8d83d3567a60280291c0adb95d1d60335509)
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