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{{.*}}(
postfix_before_args()56 void 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{{.*}}(
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{{.*}}(
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{{.*}}(
alloc_before_init()126 void 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{{.*}}(
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{{.*}}(
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{{.*}}(
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{{.*}}(
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{{.*}}(
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 }
272