diff options
Diffstat (limited to 'test/CodeGenCXX/cxx1z-eval-order.cpp')
-rw-r--r-- | test/CodeGenCXX/cxx1z-eval-order.cpp | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/test/CodeGenCXX/cxx1z-eval-order.cpp b/test/CodeGenCXX/cxx1z-eval-order.cpp new file mode 100644 index 0000000000000..1106719a4748f --- /dev/null +++ b/test/CodeGenCXX/cxx1z-eval-order.cpp @@ -0,0 +1,271 @@ +// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple %itanium_abi_triple | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ITANIUM +// 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 + +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->(); + void operator->*(A); + friend void operator->*(C, B); + + friend void operator<<(C, B); + friend void operator>>(C, B); + void operator<<(A); + void operator>>(A); + + 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); +}; + +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( + // CHECK-WINDOWS: call {{.*}}@"\01??0A@@Q{{AE|EAA}}@XZ"( + // CHECK: call {{.*}}%{{.*}}( + get_f()(A{}); + + // CHECK: call {{.*}}@{{.*}}side_effect{{.*}}( + // CHECK-ITANIUM: call {{.*}}@_ZN1AC1Ev( + // CHECK-WINDOWS: call {{.*}}@"\01??0A@@Q{{AE|EAA}}@XZ"( + // 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{{.*}}( + // CHECK-WINDOWS: call {{.*}}@"\01??2@YAP{{EAX_K|AXI}}@Z"( + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + delete new Q(make_a()); + + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + new (make_c()) Q(make_a()); +// CHECK: } +} + + +// CHECK-LABEL: define {{.*}}@{{.*}}dotstar_lhs_before_rhs{{.*}}( +int dotstar_lhs_before_rhs() { + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_mem_ptr_a{{.*}}( + int a = make_a().*make_mem_ptr_a(); + + // CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_mem_ptr_a{{.*}}( + int b = make_a_ptr()->*make_mem_ptr_a(); + + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + make_c()->*make_a(); + + // 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{{.*}}( + make_c()->*make_b(); + + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_mem_fn_ptr_a{{.*}}( + // CHECK: call + (make_a().*make_mem_fn_ptr_a())(); + + // CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_mem_fn_ptr_a{{.*}}( + // CHECK: call + (make_a_ptr()->*make_mem_fn_ptr_a())(); + + return a + b; +// CHECK: } +} + + +// CHECK-LABEL: define {{.*}}@{{.*}}assign_rhs_before_lhs{{.*}}( +void assign_rhs_before_lhs() { + extern int &lhs_ref(), rhs(); + + // CHECK: call {{.*}}@{{.*}}rhs{{.*}}( + // CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}( + lhs_ref() = rhs(); + + // CHECK: call {{.*}}@{{.*}}rhs{{.*}}( + // CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}( + lhs_ref() += rhs(); + + // CHECK: call {{.*}}@{{.*}}rhs{{.*}}( + // CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}( + lhs_ref() %= rhs(); + + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + make_c() = make_a(); + + // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + make_c() += make_a(); + + // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + make_c() += make_b(); +// CHECK: } +} + +// CHECK-LABEL: define {{.*}}@{{.*}}shift_lhs_before_rhs{{.*}}( +void shift_lhs_before_rhs() { + extern int lhs(), rhs(); + + // CHECK: call {{.*}}@{{.*}}lhs{{.*}}( + // CHECK: call {{.*}}@{{.*}}rhs{{.*}}( + (void)(lhs() << rhs()); + + // CHECK: call {{.*}}@{{.*}}lhs{{.*}}( + // CHECK: call {{.*}}@{{.*}}rhs{{.*}}( + (void)(lhs() >> 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(); + + // FIXME: This is not correct for Windows ABIs, see above. + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( + make_c() << make_b(); + + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( + make_c() >> make_b(); +// 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(); + + // FIXME: This is not correct for Windows ABIs, see above. + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( + 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(); + + // FIXME: This is not correct for Windows ABIs, see above. + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( + make_c() && make_b(); + + // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( + make_c() || make_b(); +} |