diff options
Diffstat (limited to 'gcc/testsuite')
27 files changed, 658 insertions, 6 deletions
diff --git a/gcc/testsuite/c-c++-common/cpp/spaceship-1.c b/gcc/testsuite/c-c++-common/cpp/spaceship-1.c new file mode 100644 index 0000000..a3dc38d --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/spaceship-1.c @@ -0,0 +1,6 @@ +/* { dg-do preprocess } */ +/* { dg-options "-std=c11" { target c } } */ + +#define A(x, y) x##y +A(<=, >) /* { dg-error "does not give a valid preprocessing token" "" { target { ! c++2a } } } */ +A(<=>, >) /* { dg-error "does not give a valid preprocessing token" "" { target c++2a } } */ diff --git a/gcc/testsuite/g++.dg/cpp/spaceship-1.C b/gcc/testsuite/g++.dg/cpp/spaceship-1.C new file mode 100644 index 0000000..241b277 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp/spaceship-1.C @@ -0,0 +1,8 @@ +// { dg-do compile { target c++17_down } } +// { dg-options "-Wno-pointer-arith" } + +struct X {}; +bool operator<= (X, X); +template<bool (X, X)> struct Y {}; +Y<&operator<=> y; +bool foo (bool (*fn) (X, X), int n) { return n+&operator<=> fn; } diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-constexpr1.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-constexpr1.C new file mode 100644 index 0000000..9d008f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-constexpr1.C @@ -0,0 +1,15 @@ +// { dg-do compile { target c++2a } } + +struct A +{ + int i; + bool operator==(A a) const { return i == a.i; } +}; + +struct B +{ + A a; + bool operator==(const B&) const = default; // { dg-error "A::operator==" } +}; + +constexpr bool x = B() == B(); // { dg-error "non-.constexpr" } diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-eq1.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq1.C new file mode 100644 index 0000000..19a03fb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq1.C @@ -0,0 +1,17 @@ +// { dg-do run { target c++2a } } + +struct D +{ + int i; + bool operator==(const D& x) const = default; // OK, returns x.i == y.i + bool operator!=(const D& z) const = default; // OK, returns !(*this == z) +}; + +#define assert(X) do { if (!(X)) __builtin_abort(); } while (0) + +int main() +{ + D d{42}; + assert (d == d); + assert (!(d != d)); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-eq1a.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq1a.C new file mode 100644 index 0000000..7e98c47 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq1a.C @@ -0,0 +1,24 @@ +// { dg-do run { target c++2a } } + +template <class T> +struct D +{ + T i; + bool operator==(const D& x) const = default; // OK, returns x.i == y.i + bool operator!=(const D& z) const = default; // OK, returns !(*this == z) +}; + +#define assert(X) do { if (!(X)) __builtin_abort(); } while (0) + +template <class T> +void f() +{ + D<T> d{42}; + assert (d == d); + assert (!(d != d)); +} + +int main() +{ + f<int>(); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-eq2.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq2.C new file mode 100644 index 0000000..06b988f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq2.C @@ -0,0 +1,12 @@ +// { dg-do compile { target c++2a } } + +struct D +{ + int i; + bool operator==(const D& x) const = default; // OK, returns x.i == y.i + bool operator!=(const D& z) const = default; // OK, returns !(*this == z) +}; + +constexpr D d{42}; +static_assert (d == d); +static_assert (!(d != d)); diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-eq3.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq3.C new file mode 100644 index 0000000..490726d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq3.C @@ -0,0 +1,16 @@ +// { dg-do compile { target c++2a } } + +struct A { + bool operator==(const A&) const; +}; + +struct D +{ + A i; + bool operator==(const D& x) const = default; // { dg-error "A::operator==" } + bool operator!=(const D& z) const = default; // { dg-error "D::operator==" } +}; + +constexpr D d{A()}; +static_assert (d == d); // { dg-error "non-constant|constexpr" } +static_assert (!(d != d)); // { dg-error "non-constant|constexpr" } diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-eq4.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq4.C new file mode 100644 index 0000000..d89fc88 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq4.C @@ -0,0 +1,8 @@ +// { dg-do compile { target c++2a } } + +struct A { + int operator==(const A&) const = default; // { dg-error "return .bool" } + bool operator==(const A&, const A&) const = default; // { dg-error "exactly one" } + bool operator==(int) const = default; // { dg-error "parameter type" } + bool operator==(const A&) = default; // { dg-error "const" } +}; diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-eq5.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq5.C new file mode 100644 index 0000000..ac24f36 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq5.C @@ -0,0 +1,10 @@ +// { dg-do compile { target c++2a } } + +struct A { + int &r; // { dg-message "reference" } + bool operator==(const A&) const = default; // { dg-message "deleted" } +}; + +int i; +A a { i }; +bool b = a == a; // { dg-error "deleted" } diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-eq6.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq6.C new file mode 100644 index 0000000..f804e13 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq6.C @@ -0,0 +1,10 @@ +// { dg-do compile { target c++2a } } + +struct A +{ + union { int i; } // { dg-message "union" } + bool operator==(const A&) const = default; // { dg-message "deleted" } +}; + +A a { 42 }; +bool b = a == a; // { dg-error "deleted" } diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-eq7.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq7.C new file mode 100644 index 0000000..8112eaa --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq7.C @@ -0,0 +1,10 @@ +// { dg-do compile { target c++2a } } + +union A +{ + int i; + bool operator==(const A&) const = default; // { dg-message "union" } +}; + +A a { 42 }; +bool b = a == a; // { dg-error "deleted" } diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-err1.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-err1.C new file mode 100644 index 0000000..ce7b56c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-err1.C @@ -0,0 +1,5 @@ +// Test that we suggest adding #include <compare>. +// { dg-do compile { target c++2a } } + +auto x = 1<=>2; // { dg-error "" } +// { dg-message "<compare>" "" { target *-*-* } .-1 } diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-err2.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-err2.C new file mode 100644 index 0000000..6461c6a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-err2.C @@ -0,0 +1,7 @@ +// { dg-do compile { target c++2a } } + +#include <compare> +template <class T, T x = (T() <=> T())> // { dg-error "31:0 <=> 0" } +void f(T); +//constexpr int f(...) { return 42; } +constexpr int i = f(24); // { dg-error "no match" } diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-rewrite1.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-rewrite1.C new file mode 100644 index 0000000..bb60302 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-rewrite1.C @@ -0,0 +1,15 @@ +// This should continue to work. +// { dg-do compile { target c++2a } } + +template<class T> +struct A { + template<class U> + bool operator==(const A<U>&); +}; + +int main() +{ + A<int> a1; + A<void> a2; + return a1 == a2; +} diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-scalar1.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-scalar1.C new file mode 100644 index 0000000..2ca86b7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-scalar1.C @@ -0,0 +1,93 @@ +// { dg-do run { target c++2a } } + +#include <compare> + +#define assert(X) do { if (!(X)) __builtin_abort(); } while(0) + +void f(){} +void g(){} + +int main() +{ + { + constexpr auto v = 1 <=> 2; + static_assert (__is_same_as (decltype (v), const std::strong_ordering)); + static_assert (!is_eq (v)); + static_assert (is_neq (v)); + static_assert (is_lt (v)); + static_assert (is_lteq (v)); + static_assert (!is_gt (v)); + static_assert (!is_gteq (v)); + } + + { + enum E { a = 0 }; + constexpr auto v = E::a <=> 1; + static_assert (__is_same_as (decltype (v), const std::strong_ordering)); + static_assert (!is_eq (v)); + static_assert (is_neq (v)); + static_assert (is_lt (v)); + static_assert (is_lteq (v)); + static_assert (!is_gt (v)); + static_assert (!is_gteq (v)); + } + + { + enum class E { a, b }; + constexpr auto v = E::a <=> E::b; + static_assert (__is_same_as (decltype (v), const std::strong_ordering)); + static_assert (!is_eq (v)); + static_assert (is_neq (v)); + static_assert (is_lt (v)); + static_assert (is_lteq (v)); + static_assert (!is_gt (v)); + static_assert (!is_gteq (v)); + } + + { + int ar[2]; + constexpr auto v = &ar[1] <=> &ar[0]; + static_assert (__is_same_as (decltype (v), const std::strong_ordering)); + static_assert (!is_eq (v)); + static_assert (is_neq (v)); + static_assert (!is_lt (v)); + static_assert (!is_lteq (v)); + static_assert (is_gt (v)); + static_assert (is_gteq (v)); + } + + { + constexpr auto v = 3.14 <=> 3.14; + static_assert (__is_same_as (decltype (v), const std::partial_ordering)); + static_assert (is_eq (v)); + static_assert (!is_neq (v)); + static_assert (!is_lt (v)); + static_assert (is_lteq (v)); + static_assert (!is_gt (v)); + static_assert (is_gteq (v)); + } + + { + // GCC doesn't consider &f == &g to be a constant expression (PR 69681) + const auto v = &f <=> &g; + static_assert (__is_same_as (decltype (v), const std::strong_equality)); + assert (!is_eq (v)); + assert (is_neq (v)); + } + + { + struct A { int i; int j; }; + constexpr auto v = &A::i <=> &A::j; + static_assert (__is_same_as (decltype (v), const std::strong_equality)); + static_assert (!is_eq (v)); + static_assert (is_neq (v)); + } + + { + struct A { void f(); }; + constexpr auto v = &A::f <=> &A::f; + static_assert (__is_same_as (decltype (v), const std::strong_equality)); + static_assert (is_eq (v)); + static_assert (!is_neq (v)); + } +} diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-scalar1a.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-scalar1a.C new file mode 100644 index 0000000..1dc9549 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-scalar1a.C @@ -0,0 +1,41 @@ +// { dg-do run { target c++2a } } + +#include <compare> + +#define assert(X) do { if (!(X)) __builtin_abort(); } while(0) + +void f(){} +void g(){} + +template <class T, class U, class R> +constexpr bool check(T a, U b, R expected) +{ + auto r = a <=> b; + static_assert (__is_same_as (decltype (r), R)); + return r == expected; +} + +int main() +{ + static_assert (check (1, 2, std::strong_ordering::less)); + + enum E1 { a = 0 }; + static_assert (check (a, 1, std::strong_ordering::less)); + + enum class E2 { a, b }; + static_assert (check (E2::a, E2::b, std::strong_ordering::less)); + + int ar[2]; + static_assert (check (&ar[1], &ar[0], std::strong_ordering::greater)); + + static_assert (check (3.14, 3.14, std::partial_ordering::equivalent)); + + // GCC doesn't consider &f == &g to be a constant expression (PR 69681) + assert (check (&f, &g, std::strong_equality::nonequal)); + + struct A { int i; int j; }; + static_assert (check (&A::i, &A::j, std::strong_equality::nonequal)); + + struct A2 { void f(); }; + static_assert (check (&A2::f, &A2::f, std::strong_equality::equal)); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-scalar2.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-scalar2.C new file mode 100644 index 0000000..d3cb0a6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-scalar2.C @@ -0,0 +1,11 @@ +// { dg-do compile { target c++2a } } + +#include <compare> + +int main() +{ + { true <=> 1; } // { dg-error "bool" } + { int a[2]; a <=> a; } // { dg-error "2" } + { -1 <=> 1U; } // { dg-error "narrowing" } + { enum A { a }; enum B { b }; a <=> b; } // { dg-error "A" } +} diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-scalar3.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-scalar3.C new file mode 100644 index 0000000..20bc8e6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-scalar3.C @@ -0,0 +1,21 @@ +// { dg-do run { target c++2a } } +// { dg-options "-fext-numeric-literals" } + +#include <compare> + +int main() +{ + // GCC complex literal extension + { + constexpr auto v = 1 <=> 1i; + static_assert (__is_same_as (decltype (v), const std::strong_equality)); + static_assert (!is_eq (v)); + static_assert (is_neq (v)); + } + { + constexpr auto v = 1i <=> 1.0i; + static_assert (__is_same_as (decltype (v), const std::weak_equality)); + static_assert (is_eq (v)); + static_assert (!is_neq (v)); + } +} diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-sfinae1.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-sfinae1.C new file mode 100644 index 0000000..6a03f54 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-sfinae1.C @@ -0,0 +1,7 @@ +// { dg-do compile { target c++2a } } + +// missing #include <compare> +template <class T, T x = (T() <=> T()) == 0> +void f(T); +constexpr int f(...) { return 42; } +constexpr int i = f(24); diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-synth1.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth1.C new file mode 100644 index 0000000..2a35de9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth1.C @@ -0,0 +1,43 @@ +// Test with all operators explicitly defaulted. +// { dg-do run { target c++2a } } + +#include <compare> + +struct D +{ + int i; + auto operator<=>(const D& x) const = default; + bool operator==(const D& x) const = default; + bool operator!=(const D& x) const = default; + bool operator<(const D& x) const = default; + bool operator<=(const D& x) const = default; + bool operator>(const D& x) const = default; + bool operator>=(const D& x) const = default; +}; + +#define assert(X) do { if (!(X)) __builtin_abort(); } while (0) + +int main() +{ + D d{42}; + D d2{24}; + + assert (is_eq (d <=> d)); + assert (is_lteq (d <=> d)); + assert (is_gteq (d <=> d)); + assert (is_lt (d2 <=> d)); + assert (is_lteq (d2 <=> d)); + assert (is_gt (d <=> d2)); + assert (is_gteq (d <=> d2)); + + assert (d == d); + assert (!(d2 == d)); + assert (!(d == d2)); + assert (d != d2); + assert (!(d2 != d2)); + + assert (d2 < d); + assert (d2 <= d); + assert (d > d2); + assert (d >= d2); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-synth1a.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth1a.C new file mode 100644 index 0000000..3231457 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth1a.C @@ -0,0 +1,113 @@ +// Test with all operators explicitly defaulted. +// { dg-do run { target c++2a } } + +#include <compare> + +template <class T> +struct D +{ + T i; + auto operator<=>(const D& x) const = default; + bool operator==(const D& x) const = default; + bool operator!=(const D& x) const = default; + bool operator<(const D& x) const = default; + bool operator<=(const D& x) const = default; + bool operator>(const D& x) const = default; + bool operator>=(const D& x) const = default; +}; + +template <class T> +struct E +{ + T i; + auto operator<=>(const E& x) const = default; + // auto operator==(const E& x) const = default; + // auto operator!=(const E& x) const = default; + // auto operator<(const E& x) const = default; + // auto operator<=(const E& x) const = default; + // auto operator>(const E& x) const = default; + // auto operator>=(const E& x) const = default; +}; + +template <class T> +struct F +{ + T i; + constexpr auto operator<=>(T x) const { return i<=>x; } + constexpr bool operator== (T x) const { return i==x; } +}; + +#define assert(X) do { if (!(X)) __builtin_abort(); } while (0) + +template <class T, class U> +constexpr bool check_eq (T d, U d2) +{ + return is_eq (d <=> d2) + && is_eq (d2 <=> d) + && is_lteq (d <=> d2) + && is_lteq (d2 <=> d) + && !is_lt (d <=> d2) + && !is_lt (d2 <=> d) + && is_gteq (d <=> d2) + && is_gteq (d2 <=> d) + && !is_gt (d <=> d2) + && !is_gt (d2 <=> d) + && d == d2 + && d2 == d + && !(d != d2) + && !(d2 != d) + && d >= d2 + && d <= d2 + && d2 >= d + && d2 <= d + && !(d < d2) + && !(d2 < d) + && !(d > d2) + && !(d2 > d); +} + +template <class T, class U> +constexpr bool check_less (T d, U d2) +{ + return !is_eq (d <=> d2) + && !is_eq (d2 <=> d) + && is_lteq (d <=> d2) + && !is_lteq (d2 <=> d) + && is_lt (d <=> d2) + && !is_lt (d2 <=> d) + && !is_gteq (d <=> d2) + && is_gteq (d2 <=> d) + && !is_gt (d <=> d2) + && is_gt (d2 <=> d) + && !(d == d2) + && !(d2 == d) + && (d != d2) + && (d2 != d) + && !(d >= d2) + && (d <= d2) + && (d2 >= d) + && !(d2 <= d) + && (d < d2) + && !(d2 < d) + && !(d > d2) + && (d2 > d); +} + +int main() +{ + constexpr D<int> d{42}; + constexpr D<int> d2{24}; + + static_assert (check_eq (d, d)); + static_assert (check_less (d2, d)); + + constexpr E<float> e { 3.14 }; + constexpr E<float> ee { 2.72 }; + static_assert (check_eq (e, e)); + static_assert (check_less (ee, e)); + + constexpr F<char> f { 'b' }; + static_assert (check_eq (f, 'b')); + static_assert (check_less (f, 'c')); + static_assert (check_less ('a', f)); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-synth2.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth2.C new file mode 100644 index 0000000..cf23c97 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth2.C @@ -0,0 +1,43 @@ +// Test with only spaceship defaulted. +// { dg-do run { target c++2a } } + +#include <compare> + +struct D +{ + int i; + auto operator<=>(const D& x) const = default; + // auto operator==(const D& x) const = default; + // auto operator!=(const D& x) const = default; + // auto operator<(const D& x) const = default; + // auto operator<=(const D& x) const = default; + // auto operator>(const D& x) const = default; + // auto operator>=(const D& x) const = default; +}; + +#define assert(X) do { if (!(X)) __builtin_abort(); } while (0) + +int main() +{ + D d{42}; + D d2{24}; + + assert (is_eq (d <=> d)); + assert (is_lteq (d <=> d)); + assert (is_gteq (d <=> d)); + assert (is_lt (d2 <=> d)); + assert (is_lteq (d2 <=> d)); + assert (is_gt (d <=> d2)); + assert (is_gteq (d <=> d2)); + + assert (d == d); + assert (!(d2 == d)); + assert (!(d == d2)); + assert (d != d2); + assert (!(d2 != d2)); + + assert (d2 < d); + assert (d2 <= d); + assert (d > d2); + assert (d >= d2); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-synth3.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth3.C new file mode 100644 index 0000000..0fc5aa2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth3.C @@ -0,0 +1,48 @@ +// Test for reversed candidates. +// { dg-do run { target c++2a } } + +#include <compare> + +struct D +{ + int i; + auto operator<=>(int x) const { return i<=>x; } + bool operator== (int x) const { return i==x; } +}; + +#define assert(X) do { if (!(X)) __builtin_abort(); } while (0) + +int main() +{ + D d{42}; + int d1 = 42; + int d2 = 24; + + assert (is_eq (d <=> d1)); + assert (is_eq (d1 <=> d)); + assert (is_lteq (d <=> d1)); + assert (is_lteq (d1 <=> d)); + assert (is_gteq (d <=> d1)); + assert (is_gteq (d1 <=> d)); + assert (is_lt (d2 <=> d)); + assert (is_lteq (d2 <=> d)); + assert (is_gt (d <=> d2)); + assert (is_gteq (d <=> d2)); + + assert (d == d1); + assert (d1 == d); + assert (!(d2 == d)); + assert (!(d == d2)); + assert (d != d2); + assert (d2 != d); + assert (!(d != d1)); + assert (!(d1 != d)); + + assert (d2 < d); + assert (d2 <= d); + assert (d1 <= d); + assert (d > d2); + assert (d >= d2); + assert (d >= d1); + assert (d <= d1); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-synth3a.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth3a.C new file mode 100644 index 0000000..89f8489 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth3a.C @@ -0,0 +1,54 @@ +// Test for reversed candidates. +// { dg-do run { target c++2a } } + +#include <compare> + +struct D +{ + int i; + auto operator<=>(int x) const { return i<=>x; } + bool operator== (int x) const { return i==x; } +}; + +#define assert(X) do { if (!(X)) __builtin_abort(); } while (0) + +template <class T> +void f() +{ + D d{42}; + int d1 = 42; + int d2 = 24; + + assert (is_eq (d <=> d1)); + assert (is_eq (d1 <=> d)); + assert (is_lteq (d <=> d1)); + assert (is_lteq (d1 <=> d)); + assert (is_gteq (d <=> d1)); + assert (is_gteq (d1 <=> d)); + assert (is_lt (d2 <=> d)); + assert (is_lteq (d2 <=> d)); + assert (is_gt (d <=> d2)); + assert (is_gteq (d <=> d2)); + + assert (d == d1); + assert (d1 == d); + assert (!(d2 == d)); + assert (!(d == d2)); + assert (d != d2); + assert (d2 != d); + assert (!(d != d1)); + assert (!(d1 != d)); + + assert (d2 < d); + assert (d2 <= d); + assert (d1 <= d); + assert (d > d2); + assert (d >= d2); + assert (d >= d1); + assert (d <= d1); +} + +int main() +{ + f<int>(); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-weak1.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-weak1.C new file mode 100644 index 0000000..1ff3954 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-weak1.C @@ -0,0 +1,15 @@ +// Test explicit weak_ordering. +// { dg-do compile { target c++2a } } + +#include <compare> +struct A +{ + int i; + std::weak_ordering operator<=> (const A&) const = default; +}; + +constexpr A a = { 42 }; +constexpr auto c = a <=> a; +static_assert (std::same_as <decltype (c), const std::weak_ordering>); +static_assert (std::is_eq (c)); + diff --git a/gcc/testsuite/g++.dg/lookup/pr21802.C b/gcc/testsuite/g++.dg/lookup/pr21802.C index 139f7b4..18b2219 100644 --- a/gcc/testsuite/g++.dg/lookup/pr21802.C +++ b/gcc/testsuite/g++.dg/lookup/pr21802.C @@ -60,6 +60,7 @@ struct Y : virtual X template <typename T> int operator&(T x) { return m + x + 1; } friend int operator==(Y o, int x) { return o.m + x + 1; } + int operator!=(int x) { return m + x + 1; } }; /* The folloiwng "FooN" functions each contain a different way to call and to @@ -81,7 +82,6 @@ Foo1 (T) { int t = x | I; assert (t == 7); } { int t = x && I; assert (t == 7); } { int t = x || I; assert (t == 7); } - { int t = x != I; assert (t == 7); } { int t = x < I; assert (t == 7); } { int t = x <= I; assert (t == 7); } { int t = x > I; assert (t == 7); } @@ -104,6 +104,7 @@ Foo1 (T) { int t = x & I; assert (t == 8); } { int t = &x; assert (t == 8); } { int t = x == I; assert (t == 8); } + { int t = x != I; assert (t == 8); } } template <typename T> @@ -204,7 +205,6 @@ Foo4 (T) { int t = x.operator| (I); assert (t == 7); } { int t = x.operator&& (I); assert (t == 7); } { int t = x.operator|| (I); assert (t == 7); } - { int t = x.operator!= (I); assert (t == 7); } { int t = x.operator< (I); assert (t == 7); } { int t = x.operator<= (I); assert (t == 7); } { int t = x.operator> (I); assert (t == 7); } @@ -227,6 +227,7 @@ Foo4 (T) { int t = x.operator& (); assert (t == 8); } { int t = x.operator& (I); assert (t == 8); } { int t = operator== (x, I); assert (t == 8); } + { int t = x.operator!= (I); assert (t == 8); } } diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb22.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb22.C index 62dd18d..c0921bb 100644 --- a/gcc/testsuite/g++.old-deja/g++.robertl/eb22.C +++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb22.C @@ -11,18 +11,17 @@ public: operator int() const {return 2;} }; -bool operator==(const MyInt& a, const int& b) // { dg-message "operator==" } candidate +bool operator==(const MyInt& a, const int& b) // { dg-message "operator==" "" { target c++17_down } } { return (int)a == b; } -bool operator==(const MyInt& a, const MyInt& b) // { dg-message "operator==" } candidate +bool operator==(const MyInt& a, const MyInt& b) // { dg-message "operator==" "" { target c++17_down } } { return (int)a == (int)b; } bool f() { - return 3 == MyInt(); // { dg-error "ambiguous" "err" } - // { dg-message "operator==" "match candidate text" { target *-*-* } .-1 } + return 3 == MyInt(); // { dg-error "ambiguous" "err" { target c++17_down } } } |