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 {{.*}}@"??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{{.*}}( |
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 {{.*}}@"??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 | } |
272 | |