]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGenCXX/cxx1z-eval-order.cpp
Vendor import of clang trunk r290819:
[FreeBSD/FreeBSD.git] / 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
5 struct B;
6 struct A {
7   A();
8   A(const A&);
9
10   void operator[](B b);
11
12   int a_member_f(B);
13 };
14 struct B {
15   B();
16   ~B();
17 };
18
19 struct 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
43 A make_a();
44 A *make_a_ptr();
45 int A::*make_mem_ptr_a();
46 void (A::*make_mem_fn_ptr_a())();
47 B make_b();
48 C make_c();
49 void side_effect();
50
51 void callee(A);
52 void (*get_f())(A);
53
54
55 // CHECK-LABEL: define {{.*}}@{{.*}}postfix_before_args{{.*}}(
56 void postfix_before_args() {
57   // CHECK: call {{.*}}@{{.*}}get_f{{.*}}(
58   // CHECK-ITANIUM: call {{.*}}@_ZN1AC1Ev(
59   // CHECK-WINDOWS: call {{.*}}@"\01??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 {{.*}}@"\01??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{{.*}}(
73 void 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{{.*}}(
93 void 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
123 void *operator new(decltype(sizeof(0)), C);
124
125 // CHECK-LABEL: define {{.*}}@{{.*}}alloc_before_init{{.*}}(
126 void alloc_before_init() {
127   struct Q { Q(A) {} };
128   // CHECK-ITANIUM: call {{.*}}@_Znw{{.*}}(
129   // CHECK-WINDOWS: call {{.*}}@"\01??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{{.*}}(
141 int 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{{.*}}(
181 void 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{{.*}}(
211 void 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{{.*}}(
242 void 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{{.*}}(
254 void 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 }