1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
10 
11 // <compare>
12 
13 // Ensure we reject all cases where an argument other than a literal 0 is used
14 // for a comparison against a comparison category type.
15 
16 // Also ensure that we don't warn about providing a null pointer constant when
17 // comparing an ordering type against literal 0, since one of the common
18 // implementation strategies is to use a pointer as the "unspecified type".
19 // ADDITIONAL_COMPILE_FLAGS: -Wzero-as-null-pointer-constant
20 
21 #include <compare>
22 
23 #include "test_macros.h"
24 
25 #define TEST_FAIL(v, op)                                                                                               \
26   do {                                                                                                                 \
27     /* invalid types */                                                                                                \
28     void(v op 0L);                                                                                                     \
29     void(0L op v);                                                                                                     \
30     void(v op 0.0);                                                                                                    \
31     void(0.0 op v);                                                                                                    \
32     void(v op nullptr);                                                                                                \
33     void(nullptr op v);                                                                                                \
34     /* invalid value */                                                                                                \
35     void(v op 1);                                                                                                      \
36     void(1 op v);                                                                                                      \
37     /* value not known at compile-time */                                                                              \
38     int i = 0;                                                                                                         \
39     void(v op i);                                                                                                      \
40     void(i op v);                                                                                                      \
41   } while (false)
42 
43 #define TEST_PASS(v, op)                                                                                               \
44   do {                                                                                                                 \
45     void(v op 0);                                                                                                      \
46     void(0 op v);                                                                                                      \
47     LIBCPP_ONLY(void(v op(1 - 1)));                                                                                    \
48     LIBCPP_ONLY(void((1 - 1) op v));                                                                                   \
49   } while (false)
50 
51 template <typename T>
52 void test_category(T v) {
53   TEST_FAIL(v, ==);  // expected-error 30 {{invalid operands to binary expression}}
54   TEST_FAIL(v, !=);  // expected-error 30 {{invalid operands to binary expression}}
55   TEST_FAIL(v, <);   // expected-error 30 {{invalid operands to binary expression}}
56   TEST_FAIL(v, <=);  // expected-error 30 {{invalid operands to binary expression}}
57   TEST_FAIL(v, >);   // expected-error 30 {{invalid operands to binary expression}}
58   TEST_FAIL(v, >=);  // expected-error 30 {{invalid operands to binary expression}}
59   TEST_FAIL(v, <=>); // expected-error 30 {{invalid operands to binary expression}}
60 
61   TEST_PASS(v, ==);
62   TEST_PASS(v, !=);
63   TEST_PASS(v, <);
64   TEST_PASS(v, >);
65   TEST_PASS(v, <=);
66   TEST_PASS(v, >=);
67   TEST_PASS(v, <=>);
68 }
69 
70 void f() {
71   test_category(std::strong_ordering::equivalent);
72   test_category(std::weak_ordering::equivalent);
73   test_category(std::partial_ordering::equivalent);
74 }
75