Clang Project

clang_source_code/test/CodeGenCXX/cxx1z-eval-order.cpp
1// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple %itanium_abi_triple | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ITANIUM
2// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple i686-windows | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-WINDOWS
3// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-windows | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-WINDOWS
4
5struct B;
6struct A {
7  A();
8  A(const A&);
9
10  void operator[](B b);
11
12  int a_member_f(B);
13};
14struct B {
15  B();
16  ~B();
17};
18
19struct C {
20  operator int *();
21  A *operator->();
22  void operator->*(A);
23  friend void operator->*(C, B);
24
25  friend void operator<<(C, B);
26  friend void operator>>(C, B);
27  void operator<<(A);
28  void operator>>(A);
29
30  void operator=(A);
31  void operator+=(A);
32  friend void operator+=(C, B);
33
34  void operator,(A);
35  friend void operator,(C, B);
36
37  void operator&&(A);
38  void operator||(A);
39  friend void operator&&(C, B);
40  friend void operator||(C, B);
41};
42
43A make_a();
44A *make_a_ptr();
45int A::*make_mem_ptr_a();
46void (A::*make_mem_fn_ptr_a())();
47B make_b();
48C make_c();
49void side_effect();
50
51void callee(A);
52void (*get_f())(A);
53
54
55// CHECK-LABEL: define {{.*}}@{{.*}}postfix_before_args{{.*}}(
56void postfix_before_args() {
57  // CHECK: call {{.*}}@{{.*}}get_f{{.*}}(
58  // CHECK-ITANIUM: call {{.*}}@_ZN1AC1Ev(
59  // CHECK-WINDOWS: call {{.*}}@"??0A@@Q{{AE|EAA}}@XZ"(
60  // CHECK: call {{.*}}%{{.*}}(
61  get_f()(A{});
62
63  // CHECK: call {{.*}}@{{.*}}side_effect{{.*}}(
64  // CHECK-ITANIUM: call {{.*}}@_ZN1AC1Ev(
65  // CHECK-WINDOWS: call {{.*}}@"??0A@@Q{{AE|EAA}}@XZ"(
66  // CHECK: call {{.*}}@{{.*}}callee{{.*}}(
67  (side_effect(), callee)(A{});
68// CHECK: }
69}
70
71
72// CHECK-LABEL: define {{.*}}@{{.*}}dot_lhs_before_rhs{{.*}}(
73void dot_lhs_before_rhs() {
74  // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
75  // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
76  // CHECK: call {{.*}}@{{.*}}a_member_f{{.*}}(
77  make_a().a_member_f(make_b());
78
79  // CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}(
80  // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
81  // CHECK: call {{.*}}@{{.*}}a_member_f{{.*}}(
82  make_a_ptr()->a_member_f(make_b());
83
84  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
85  // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
86  // CHECK: call {{.*}}@{{.*}}a_member_f{{.*}}(
87  make_c()->a_member_f(make_b());
88// CHECK: }
89}
90
91
92// CHECK-LABEL: define {{.*}}@{{.*}}array_lhs_before_rhs{{.*}}(
93void array_lhs_before_rhs() {
94  int (&get_arr())[10];
95  extern int get_index();
96
97  // CHECK: call {{.*}}@{{.*}}get_arr{{.*}}(
98  // CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
99  get_arr()[get_index()] = 0;
100
101  // CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
102  // CHECK: call {{.*}}@{{.*}}get_arr{{.*}}(
103  get_index()[get_arr()] = 0;
104
105  // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
106  // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
107  // CHECK: call
108  make_a()[make_b()];
109
110  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
111  // CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
112  // CHECK: call
113  make_c()[get_index()] = 0;
114
115  // CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
116  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
117  // CHECK: call
118  get_index()[make_c()] = 0;
119// CHECK: }
120}
121
122
123void *operator new(decltype(sizeof(0)), C);
124
125// CHECK-LABEL: define {{.*}}@{{.*}}alloc_before_init{{.*}}(
126void alloc_before_init() {
127  struct Q { Q(A) {} };
128  // CHECK-ITANIUM: call {{.*}}@_Znw{{.*}}(
129  // CHECK-WINDOWS: call {{.*}}@"??2@YAP{{EAX_K|AXI}}@Z"(
130  // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
131  delete new Q(make_a());
132
133  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
134  // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
135  new (make_c()) Q(make_a());
136// CHECK: }
137}
138
139
140// CHECK-LABEL: define {{.*}}@{{.*}}dotstar_lhs_before_rhs{{.*}}(
141int dotstar_lhs_before_rhs() {
142  // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
143  // CHECK: call {{.*}}@{{.*}}make_mem_ptr_a{{.*}}(
144  int a = make_a().*make_mem_ptr_a();
145
146  // CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}(
147  // CHECK: call {{.*}}@{{.*}}make_mem_ptr_a{{.*}}(
148  int b = make_a_ptr()->*make_mem_ptr_a();
149
150  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
151  // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
152  make_c()->*make_a();
153
154  // FIXME: For MS ABI, the order of destruction of parameters here will not be
155  // reverse construction order (parameters are destroyed left-to-right in the
156  // callee). That sadly seems unavoidable; the rules are not implementable as
157  // specified. If we changed parameter destruction order for these functions
158  // to right-to-left, we could make the destruction order match for all cases
159  // other than indirect calls, but we can't completely avoid the problem.
160  //
161  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
162  // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
163  make_c()->*make_b();
164
165  // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
166  // CHECK: call {{.*}}@{{.*}}make_mem_fn_ptr_a{{.*}}(
167  // CHECK: call
168  (make_a().*make_mem_fn_ptr_a())();
169
170  // CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}(
171  // CHECK: call {{.*}}@{{.*}}make_mem_fn_ptr_a{{.*}}(
172  // CHECK: call
173  (make_a_ptr()->*make_mem_fn_ptr_a())();
174
175  return a + b;
176// CHECK: }
177}
178
179
180// CHECK-LABEL: define {{.*}}@{{.*}}assign_rhs_before_lhs{{.*}}(
181void assign_rhs_before_lhs() {
182  extern int &lhs_ref(), rhs();
183
184  // CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
185  // CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}(
186  lhs_ref() = rhs();
187
188  // CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
189  // CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}(
190  lhs_ref() += rhs();
191
192  // CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
193  // CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}(
194  lhs_ref() %= rhs();
195
196  // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
197  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
198  make_c() = make_a();
199
200  // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
201  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
202  make_c() += make_a();
203
204  // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
205  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
206  make_c() += make_b();
207// CHECK: }
208}
209
210// CHECK-LABEL: define {{.*}}@{{.*}}shift_lhs_before_rhs{{.*}}(
211void shift_lhs_before_rhs() {
212  extern int lhs(), rhs();
213
214  // CHECK: call {{.*}}@{{.*}}lhs{{.*}}(
215  // CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
216  (void)(lhs() << rhs());
217
218  // CHECK: call {{.*}}@{{.*}}lhs{{.*}}(
219  // CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
220  (void)(lhs() >> rhs());
221
222  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
223  // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
224  make_c() << make_a();
225
226  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
227  // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
228  make_c() >> make_a();
229
230  // FIXME: This is not correct for Windows ABIs, see above.
231  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
232  // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
233  make_c() << make_b();
234
235  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
236  // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
237  make_c() >> make_b();
238// CHECK: }
239}
240
241// CHECK-LABEL: define {{.*}}@{{.*}}comma_lhs_before_rhs{{.*}}(
242void comma_lhs_before_rhs() {
243  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
244  // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
245  make_c() , make_a();
246
247  // FIXME: This is not correct for Windows ABIs, see above.
248  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
249  // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
250  make_c() , make_b();
251}
252
253// CHECK-LABEL: define {{.*}}@{{.*}}andor_lhs_before_rhs{{.*}}(
254void andor_lhs_before_rhs() {
255  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
256  // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
257  make_c() && make_a();
258
259  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
260  // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
261  make_c() || make_a();
262
263  // FIXME: This is not correct for Windows ABIs, see above.
264  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
265  // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
266  make_c() && make_b();
267
268  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
269  // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
270  make_c() || make_b();
271}
272