blob: a48bb0edf51c49aa58bde5c7cc8169644341ce60 [file] [log] [blame]
Richard Smithbc240142019-12-10 16:45:02 -08001// 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
4namespace 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
15struct Primary {
16 virtual void f();
17 std::strong_ordering operator<=>(const Primary&) const = default;
18};
19struct 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?
34struct Y : Primary, X {
35 virtual std::strong_ordering operator<=>(const Y&) const = default;
36};
37Y y;
Douglas Yungb71475f2019-12-12 17:28:06 -080038// ITANIUM: @_ZTV1Y = {{.*}}constant {{.*}} null, {{.*}} @_ZTI1Y {{.*}} @_ZN7Primary1fEv {{.*}} @_ZNK1YssERKS_ {{.*}} @_ZN1YaSERKS_ {{.*}} @_ZN1YaSEOS_ {{.*}} @_ZNK1YeqERKS_ {{.*}} -[[POINTERSIZE:4|8]]
Douglas Yungbc0c60f2019-12-12 18:22:25 -080039// ITANIUM-SAME: @_ZTI1Y {{.*}} @_ZThn[[POINTERSIZE]]_N1YaSERKS_
Richard Smithd30b23d2017-12-01 02:13:10 +000040
41struct A {
42 void operator<=>(int);
43};
44
45// ITANIUM: define {{.*}}@_ZN1AssEi(
Nico Weber27df4092019-04-23 16:37:42 +000046// MSABI: define {{.*}}@"??__MA@@QEAAXH@Z"(
Richard Smithd30b23d2017-12-01 02:13:10 +000047void A::operator<=>(int) {}
48
49// ITANIUM: define {{.*}}@_Zssi1A(
Nico Weber27df4092019-04-23 16:37:42 +000050// MSABI: define {{.*}}@"??__M@YAXHUA@@@Z"(
Richard Smithd30b23d2017-12-01 02:13:10 +000051void operator<=>(int, A) {}
Richard Smithc70f1d62017-12-14 15:16:18 +000052
53int operator<=>(A, A);
54
55// ITANIUM: define {{.*}}_Z1f1A(
Nico Weber27df4092019-04-23 16:37:42 +000056// MSABI: define {{.*}}@"?f@@YAHUA@@@Z"(
Richard Smithc70f1d62017-12-14 15:16:18 +000057int f(A a) {
58 // ITANIUM: %[[RET:.*]] = call {{.*}}_Zss1AS_(
Hans Wennborg40ccbd32018-10-26 13:05:45 +000059 // ITANIUM: ret i32 %[[RET]]
Nico Weber27df4092019-04-23 16:37:42 +000060 // MSABI: %[[RET:.*]] = call {{.*}}"??__M@YAHUA@@0@Z"(
61 // MSABI: ret i32 %[[RET]]
Richard Smithc70f1d62017-12-14 15:16:18 +000062 return a <=> a;
63}
64
Richard Smithbc240142019-12-10 16:45:02 -080065// CHECK-LABEL: define {{.*}}builtin_cmp
66void builtin_cmp(int a) {
67 // CHECK: icmp slt
68 // CHECK: select
69 // CHECK: icmp eq
70 // CHECK: select
71 a <=> a;
Richard Smithc70f1d62017-12-14 15:16:18 +000072}