272 lines · cpp
1// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple %itanium_abi_triple | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ITANIUM2// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple i686-windows | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-WINDOWS3// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-windows | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-WINDOWS4 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: call108 make_a()[make_b()];109 110 // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(111 // CHECK: call {{.*}}@{{.*}}get_index{{.*}}(112 // CHECK: call113 make_c()[get_index()] = 0;114 115 // CHECK: call {{.*}}@{{.*}}get_index{{.*}}(116 // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(117 // CHECK: call118 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 be155 // reverse construction order (parameters are destroyed left-to-right in the156 // callee). That sadly seems unavoidable; the rules are not implementable as157 // specified. If we changed parameter destruction order for these functions158 // to right-to-left, we could make the destruction order match for all cases159 // 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: call168 (make_a().*make_mem_fn_ptr_a())();169 170 // CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}(171 // CHECK: call {{.*}}@{{.*}}make_mem_fn_ptr_a{{.*}}(172 // CHECK: call173 (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