Richard Smith | bc24014 | 2019-12-10 16:45:02 -0800 | [diff] [blame] | 1 | // RUN: %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %itanium_abi_triple | FileCheck %s --check-prefixes=CHECK,ITANIUM |
| 2 | // RUN: %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple x86_64-pc-win32 2>&1 | FileCheck %s --check-prefixes=CHECK,MSABI |
| 3 | |
| 4 | namespace std { |
| 5 | struct strong_ordering { |
| 6 | int n; |
| 7 | constexpr operator int() const { return n; } |
| 8 | static const strong_ordering less, equal, greater; |
| 9 | }; |
| 10 | constexpr strong_ordering strong_ordering::less = {-1}; |
| 11 | constexpr strong_ordering strong_ordering::equal = {0}; |
| 12 | constexpr strong_ordering strong_ordering::greater = {1}; |
| 13 | } |
| 14 | |
| 15 | struct Primary { |
| 16 | virtual void f(); |
| 17 | std::strong_ordering operator<=>(const Primary&) const = default; |
| 18 | }; |
| 19 | struct X { |
| 20 | virtual struct Y &operator=(Y&&); |
| 21 | virtual struct Y &operator=(const Y&); |
| 22 | std::strong_ordering operator<=>(const X&) const = default; |
| 23 | }; |
| 24 | // The vtable for Y should contain the following entries in order: |
| 25 | // - Primary::f |
| 26 | // - Y::operator<=> |
| 27 | // - Y::operator=(const Y&) (implicit) |
| 28 | // - Y::operator=(Y&&) (implicit) |
| 29 | // - Y::operator==(const Y&) const (implicit) |
| 30 | // See: |
| 31 | // https://github.com/itanium-cxx-abi/cxx-abi/issues/83 for assignment operator |
| 32 | // https://github.com/itanium-cxx-abi/cxx-abi/issues/88 for equality comparison |
| 33 | // FIXME: What rule does MSVC use? |
| 34 | struct Y : Primary, X { |
| 35 | virtual std::strong_ordering operator<=>(const Y&) const = default; |
| 36 | }; |
| 37 | Y y; |
Douglas Yung | b71475f | 2019-12-12 17:28:06 -0800 | [diff] [blame] | 38 | // ITANIUM: @_ZTV1Y = {{.*}}constant {{.*}} null, {{.*}} @_ZTI1Y {{.*}} @_ZN7Primary1fEv {{.*}} @_ZNK1YssERKS_ {{.*}} @_ZN1YaSERKS_ {{.*}} @_ZN1YaSEOS_ {{.*}} @_ZNK1YeqERKS_ {{.*}} -[[POINTERSIZE:4|8]] |
Douglas Yung | bc0c60f | 2019-12-12 18:22:25 -0800 | [diff] [blame] | 39 | // ITANIUM-SAME: @_ZTI1Y {{.*}} @_ZThn[[POINTERSIZE]]_N1YaSERKS_ |
Richard Smith | d30b23d | 2017-12-01 02:13:10 +0000 | [diff] [blame] | 40 | |
| 41 | struct A { |
| 42 | void operator<=>(int); |
| 43 | }; |
| 44 | |
| 45 | // ITANIUM: define {{.*}}@_ZN1AssEi( |
Nico Weber | 27df409 | 2019-04-23 16:37:42 +0000 | [diff] [blame] | 46 | // MSABI: define {{.*}}@"??__MA@@QEAAXH@Z"( |
Richard Smith | d30b23d | 2017-12-01 02:13:10 +0000 | [diff] [blame] | 47 | void A::operator<=>(int) {} |
| 48 | |
| 49 | // ITANIUM: define {{.*}}@_Zssi1A( |
Nico Weber | 27df409 | 2019-04-23 16:37:42 +0000 | [diff] [blame] | 50 | // MSABI: define {{.*}}@"??__M@YAXHUA@@@Z"( |
Richard Smith | d30b23d | 2017-12-01 02:13:10 +0000 | [diff] [blame] | 51 | void operator<=>(int, A) {} |
Richard Smith | c70f1d6 | 2017-12-14 15:16:18 +0000 | [diff] [blame] | 52 | |
| 53 | int operator<=>(A, A); |
| 54 | |
| 55 | // ITANIUM: define {{.*}}_Z1f1A( |
Nico Weber | 27df409 | 2019-04-23 16:37:42 +0000 | [diff] [blame] | 56 | // MSABI: define {{.*}}@"?f@@YAHUA@@@Z"( |
Richard Smith | c70f1d6 | 2017-12-14 15:16:18 +0000 | [diff] [blame] | 57 | int f(A a) { |
| 58 | // ITANIUM: %[[RET:.*]] = call {{.*}}_Zss1AS_( |
Hans Wennborg | 40ccbd3 | 2018-10-26 13:05:45 +0000 | [diff] [blame] | 59 | // ITANIUM: ret i32 %[[RET]] |
Nico Weber | 27df409 | 2019-04-23 16:37:42 +0000 | [diff] [blame] | 60 | // MSABI: %[[RET:.*]] = call {{.*}}"??__M@YAHUA@@0@Z"( |
| 61 | // MSABI: ret i32 %[[RET]] |
Richard Smith | c70f1d6 | 2017-12-14 15:16:18 +0000 | [diff] [blame] | 62 | return a <=> a; |
| 63 | } |
| 64 | |
Richard Smith | bc24014 | 2019-12-10 16:45:02 -0800 | [diff] [blame] | 65 | // CHECK-LABEL: define {{.*}}builtin_cmp |
| 66 | void builtin_cmp(int a) { |
| 67 | // CHECK: icmp slt |
| 68 | // CHECK: select |
| 69 | // CHECK: icmp eq |
| 70 | // CHECK: select |
| 71 | a <=> a; |
Richard Smith | c70f1d6 | 2017-12-14 15:16:18 +0000 | [diff] [blame] | 72 | } |