2016-09-27 07:49:47 +08:00
|
|
|
// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple %itanium_abi_triple | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ITANIUM
|
2016-09-29 03:09:10 +08:00
|
|
|
// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple i686-windows | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-WINDOWS
|
|
|
|
// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-windows | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-WINDOWS
|
2016-09-27 07:49:47 +08:00
|
|
|
|
|
|
|
struct B;
|
|
|
|
struct A {
|
|
|
|
A();
|
|
|
|
A(const A&);
|
|
|
|
|
|
|
|
void operator[](B b);
|
|
|
|
|
|
|
|
int a_member_f(B);
|
|
|
|
};
|
|
|
|
struct B {
|
|
|
|
B();
|
|
|
|
~B();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct C {
|
|
|
|
operator int *();
|
|
|
|
A *operator->();
|
2016-09-29 03:09:10 +08:00
|
|
|
void operator->*(A);
|
|
|
|
friend void operator->*(C, B);
|
2016-09-27 07:49:47 +08:00
|
|
|
|
|
|
|
friend void operator<<(C, B);
|
|
|
|
friend void operator>>(C, B);
|
|
|
|
void operator<<(A);
|
|
|
|
void operator>>(A);
|
|
|
|
|
2016-09-29 03:09:10 +08:00
|
|
|
void operator=(A);
|
|
|
|
void operator+=(A);
|
|
|
|
friend void operator+=(C, B);
|
|
|
|
|
|
|
|
void operator,(A);
|
|
|
|
friend void operator,(C, B);
|
|
|
|
|
|
|
|
void operator&&(A);
|
|
|
|
void operator||(A);
|
|
|
|
friend void operator&&(C, B);
|
|
|
|
friend void operator||(C, B);
|
2016-09-27 07:49:47 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
A make_a();
|
|
|
|
A *make_a_ptr();
|
|
|
|
int A::*make_mem_ptr_a();
|
|
|
|
void (A::*make_mem_fn_ptr_a())();
|
|
|
|
B make_b();
|
|
|
|
C make_c();
|
|
|
|
void side_effect();
|
|
|
|
|
|
|
|
void callee(A);
|
|
|
|
void (*get_f())(A);
|
|
|
|
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}}@{{.*}}postfix_before_args{{.*}}(
|
|
|
|
void postfix_before_args() {
|
|
|
|
// CHECK: call {{.*}}@{{.*}}get_f{{.*}}(
|
|
|
|
// CHECK-ITANIUM: call {{.*}}@_ZN1AC1Ev(
|
2016-09-27 08:52:29 +08:00
|
|
|
// CHECK-WINDOWS: call {{.*}}@"\01??0A@@Q{{AE|EAA}}@XZ"(
|
2016-09-27 07:49:47 +08:00
|
|
|
// CHECK: call {{.*}}%{{.*}}(
|
|
|
|
get_f()(A{});
|
|
|
|
|
|
|
|
// CHECK: call {{.*}}@{{.*}}side_effect{{.*}}(
|
|
|
|
// CHECK-ITANIUM: call {{.*}}@_ZN1AC1Ev(
|
2016-09-27 08:52:29 +08:00
|
|
|
// CHECK-WINDOWS: call {{.*}}@"\01??0A@@Q{{AE|EAA}}@XZ"(
|
2016-09-27 07:49:47 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}callee{{.*}}(
|
|
|
|
(side_effect(), callee)(A{});
|
|
|
|
// CHECK: }
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}}@{{.*}}dot_lhs_before_rhs{{.*}}(
|
|
|
|
void dot_lhs_before_rhs() {
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}a_member_f{{.*}}(
|
|
|
|
make_a().a_member_f(make_b());
|
|
|
|
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}a_member_f{{.*}}(
|
|
|
|
make_a_ptr()->a_member_f(make_b());
|
|
|
|
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}a_member_f{{.*}}(
|
|
|
|
make_c()->a_member_f(make_b());
|
|
|
|
// CHECK: }
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}}@{{.*}}array_lhs_before_rhs{{.*}}(
|
|
|
|
void array_lhs_before_rhs() {
|
|
|
|
int (&get_arr())[10];
|
|
|
|
extern int get_index();
|
|
|
|
|
|
|
|
// CHECK: call {{.*}}@{{.*}}get_arr{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
|
|
|
|
get_arr()[get_index()] = 0;
|
|
|
|
|
|
|
|
// CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}get_arr{{.*}}(
|
|
|
|
get_index()[get_arr()] = 0;
|
|
|
|
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
|
|
|
|
// CHECK: call
|
|
|
|
make_a()[make_b()];
|
|
|
|
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
|
|
|
|
// CHECK: call
|
|
|
|
make_c()[get_index()] = 0;
|
|
|
|
|
|
|
|
// CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
|
|
|
// CHECK: call
|
|
|
|
get_index()[make_c()] = 0;
|
|
|
|
// CHECK: }
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void *operator new(decltype(sizeof(0)), C);
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}}@{{.*}}alloc_before_init{{.*}}(
|
|
|
|
void alloc_before_init() {
|
|
|
|
struct Q { Q(A) {} };
|
|
|
|
// CHECK-ITANIUM: call {{.*}}@_Znw{{.*}}(
|
2016-09-27 08:52:29 +08:00
|
|
|
// CHECK-WINDOWS: call {{.*}}@"\01??2@YAP{{EAX_K|AXI}}@Z"(
|
2016-09-27 07:49:47 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
|
|
|
|
delete new Q(make_a());
|
|
|
|
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
|
|
|
|
new (make_c()) Q(make_a());
|
|
|
|
// CHECK: }
|
|
|
|
}
|
|
|
|
|
2016-09-27 07:56:57 +08:00
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}}@{{.*}}dotstar_lhs_before_rhs{{.*}}(
|
2016-09-27 07:49:47 +08:00
|
|
|
int dotstar_lhs_before_rhs() {
|
2016-09-27 07:56:57 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_mem_ptr_a{{.*}}(
|
2016-09-27 07:49:47 +08:00
|
|
|
int a = make_a().*make_mem_ptr_a();
|
|
|
|
|
2016-09-27 07:56:57 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_mem_ptr_a{{.*}}(
|
2016-09-27 07:49:47 +08:00
|
|
|
int b = make_a_ptr()->*make_mem_ptr_a();
|
|
|
|
|
2016-09-27 07:56:57 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
2016-09-29 03:09:10 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
|
|
|
|
make_c()->*make_a();
|
|
|
|
|
Switch to a different workaround for unimplementability of P0145R3 in MS ABIs.
Instead of ignoring the evaluation order rule, ignore the "destroy parameters
in reverse construction order" rule for the small number of problematic cases.
This only causes incorrect behavior in the rare case where both parameters to
an overloaded operator <<, >>, ->*, &&, ||, or comma are of class type with
non-trivial destructor, and the program is depending on those parameters being
destroyed in reverse construction order.
We could do a little better here by reversing the order of parameter
destruction for those functions (and reversing the argument evaluation order
for all direct calls, not just those with operator syntax), but that is not a
complete solution to the problem, as the same situation can be reached by an
indirect function call.
Approach reviewed off-line by rnk.
llvm-svn: 282777
2016-09-30 05:30:12 +08:00
|
|
|
// FIXME: For MS ABI, the order of destruction of parameters here will not be
|
|
|
|
// reverse construction order (parameters are destroyed left-to-right in the
|
|
|
|
// callee). That sadly seems unavoidable; the rules are not implementable as
|
|
|
|
// specified. If we changed parameter destruction order for these functions
|
|
|
|
// to right-to-left, we could make the destruction order match for all cases
|
|
|
|
// other than indirect calls, but we can't completely avoid the problem.
|
|
|
|
//
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
|
2016-09-27 07:49:47 +08:00
|
|
|
make_c()->*make_b();
|
|
|
|
|
2016-09-27 07:56:57 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_mem_fn_ptr_a{{.*}}(
|
|
|
|
// CHECK: call
|
2016-09-27 07:49:47 +08:00
|
|
|
(make_a().*make_mem_fn_ptr_a())();
|
|
|
|
|
2016-09-27 07:56:57 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_mem_fn_ptr_a{{.*}}(
|
|
|
|
// CHECK: call
|
2016-09-27 07:49:47 +08:00
|
|
|
(make_a_ptr()->*make_mem_fn_ptr_a())();
|
|
|
|
|
|
|
|
return a + b;
|
2016-09-27 07:56:57 +08:00
|
|
|
// CHECK: }
|
2016-09-27 07:49:47 +08:00
|
|
|
}
|
2016-09-27 07:56:57 +08:00
|
|
|
|
2016-09-29 03:09:10 +08:00
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}}@{{.*}}assign_rhs_before_lhs{{.*}}(
|
2016-09-27 07:49:47 +08:00
|
|
|
void assign_rhs_before_lhs() {
|
|
|
|
extern int &lhs_ref(), rhs();
|
|
|
|
|
2016-09-29 03:09:10 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}(
|
2016-09-27 07:49:47 +08:00
|
|
|
lhs_ref() = rhs();
|
|
|
|
|
2016-09-29 03:09:10 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}(
|
2016-09-27 07:49:47 +08:00
|
|
|
lhs_ref() += rhs();
|
|
|
|
|
2016-09-29 03:09:10 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}(
|
2016-09-27 07:49:47 +08:00
|
|
|
lhs_ref() %= rhs();
|
|
|
|
|
2016-09-29 03:09:10 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
|
|
|
make_c() = make_a();
|
2016-09-27 07:49:47 +08:00
|
|
|
|
2016-09-29 03:09:10 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
|
|
|
make_c() += make_a();
|
|
|
|
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
2016-09-27 07:49:47 +08:00
|
|
|
make_c() += make_b();
|
2016-09-29 03:09:10 +08:00
|
|
|
// CHECK: }
|
2016-09-27 07:49:47 +08:00
|
|
|
}
|
2016-09-29 03:09:10 +08:00
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}}@{{.*}}shift_lhs_before_rhs{{.*}}(
|
2016-09-27 07:49:47 +08:00
|
|
|
void shift_lhs_before_rhs() {
|
|
|
|
extern int lhs(), rhs();
|
|
|
|
|
2016-09-29 03:09:10 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}lhs{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
|
2016-09-27 07:49:47 +08:00
|
|
|
(void)(lhs() << rhs());
|
|
|
|
|
2016-09-29 03:09:10 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}lhs{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
|
2016-09-27 07:49:47 +08:00
|
|
|
(void)(lhs() >> rhs());
|
|
|
|
|
2016-09-29 03:09:10 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
|
2016-09-27 07:49:47 +08:00
|
|
|
make_c() << make_a();
|
|
|
|
|
2016-09-29 03:09:10 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
|
2016-09-27 07:49:47 +08:00
|
|
|
make_c() >> make_a();
|
|
|
|
|
Switch to a different workaround for unimplementability of P0145R3 in MS ABIs.
Instead of ignoring the evaluation order rule, ignore the "destroy parameters
in reverse construction order" rule for the small number of problematic cases.
This only causes incorrect behavior in the rare case where both parameters to
an overloaded operator <<, >>, ->*, &&, ||, or comma are of class type with
non-trivial destructor, and the program is depending on those parameters being
destroyed in reverse construction order.
We could do a little better here by reversing the order of parameter
destruction for those functions (and reversing the argument evaluation order
for all direct calls, not just those with operator syntax), but that is not a
complete solution to the problem, as the same situation can be reached by an
indirect function call.
Approach reviewed off-line by rnk.
llvm-svn: 282777
2016-09-30 05:30:12 +08:00
|
|
|
// FIXME: This is not correct for Windows ABIs, see above.
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
|
2016-09-27 07:49:47 +08:00
|
|
|
make_c() << make_b();
|
|
|
|
|
Switch to a different workaround for unimplementability of P0145R3 in MS ABIs.
Instead of ignoring the evaluation order rule, ignore the "destroy parameters
in reverse construction order" rule for the small number of problematic cases.
This only causes incorrect behavior in the rare case where both parameters to
an overloaded operator <<, >>, ->*, &&, ||, or comma are of class type with
non-trivial destructor, and the program is depending on those parameters being
destroyed in reverse construction order.
We could do a little better here by reversing the order of parameter
destruction for those functions (and reversing the argument evaluation order
for all direct calls, not just those with operator syntax), but that is not a
complete solution to the problem, as the same situation can be reached by an
indirect function call.
Approach reviewed off-line by rnk.
llvm-svn: 282777
2016-09-30 05:30:12 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
|
2016-09-27 07:49:47 +08:00
|
|
|
make_c() >> make_b();
|
2016-09-29 03:09:10 +08:00
|
|
|
// CHECK: }
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}}@{{.*}}comma_lhs_before_rhs{{.*}}(
|
|
|
|
void comma_lhs_before_rhs() {
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
|
|
|
|
make_c() , make_a();
|
|
|
|
|
Switch to a different workaround for unimplementability of P0145R3 in MS ABIs.
Instead of ignoring the evaluation order rule, ignore the "destroy parameters
in reverse construction order" rule for the small number of problematic cases.
This only causes incorrect behavior in the rare case where both parameters to
an overloaded operator <<, >>, ->*, &&, ||, or comma are of class type with
non-trivial destructor, and the program is depending on those parameters being
destroyed in reverse construction order.
We could do a little better here by reversing the order of parameter
destruction for those functions (and reversing the argument evaluation order
for all direct calls, not just those with operator syntax), but that is not a
complete solution to the problem, as the same situation can be reached by an
indirect function call.
Approach reviewed off-line by rnk.
llvm-svn: 282777
2016-09-30 05:30:12 +08:00
|
|
|
// FIXME: This is not correct for Windows ABIs, see above.
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
|
2016-09-29 03:09:10 +08:00
|
|
|
make_c() , make_b();
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: define {{.*}}@{{.*}}andor_lhs_before_rhs{{.*}}(
|
|
|
|
void andor_lhs_before_rhs() {
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
|
|
|
|
make_c() && make_a();
|
|
|
|
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
|
|
|
|
make_c() || make_a();
|
|
|
|
|
Switch to a different workaround for unimplementability of P0145R3 in MS ABIs.
Instead of ignoring the evaluation order rule, ignore the "destroy parameters
in reverse construction order" rule for the small number of problematic cases.
This only causes incorrect behavior in the rare case where both parameters to
an overloaded operator <<, >>, ->*, &&, ||, or comma are of class type with
non-trivial destructor, and the program is depending on those parameters being
destroyed in reverse construction order.
We could do a little better here by reversing the order of parameter
destruction for those functions (and reversing the argument evaluation order
for all direct calls, not just those with operator syntax), but that is not a
complete solution to the problem, as the same situation can be reached by an
indirect function call.
Approach reviewed off-line by rnk.
llvm-svn: 282777
2016-09-30 05:30:12 +08:00
|
|
|
// FIXME: This is not correct for Windows ABIs, see above.
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
|
2016-09-29 03:09:10 +08:00
|
|
|
make_c() && make_b();
|
|
|
|
|
Switch to a different workaround for unimplementability of P0145R3 in MS ABIs.
Instead of ignoring the evaluation order rule, ignore the "destroy parameters
in reverse construction order" rule for the small number of problematic cases.
This only causes incorrect behavior in the rare case where both parameters to
an overloaded operator <<, >>, ->*, &&, ||, or comma are of class type with
non-trivial destructor, and the program is depending on those parameters being
destroyed in reverse construction order.
We could do a little better here by reversing the order of parameter
destruction for those functions (and reversing the argument evaluation order
for all direct calls, not just those with operator syntax), but that is not a
complete solution to the problem, as the same situation can be reached by an
indirect function call.
Approach reviewed off-line by rnk.
llvm-svn: 282777
2016-09-30 05:30:12 +08:00
|
|
|
// CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
|
|
|
|
// CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
|
2016-09-29 03:09:10 +08:00
|
|
|
make_c() || make_b();
|
2016-09-27 07:49:47 +08:00
|
|
|
}
|