Skip to content

Commit 4ca3e7d

Browse files
committed
Use diagnose_if and improve tests
1 parent 367bd44 commit 4ca3e7d

File tree

3 files changed

+59
-25
lines changed

3 files changed

+59
-25
lines changed

libcxx/include/__compare/ordering.h

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,15 @@ class weak_ordering;
3131
class strong_ordering;
3232

3333
struct _CmpUnspecifiedParam {
34-
template <class _Tp, class = __enable_if_t<is_same_v<_Tp, int>>>
35-
_LIBCPP_HIDE_FROM_ABI consteval _CmpUnspecifiedParam(_Tp __zero) noexcept {
36-
// If anything other than 0 is provided, the behavior is undefined.
37-
// We catch this case by making this function consteval and making the program ill-formed if
38-
// a value other than 0 is provided. This technically also accepts things that are not
39-
// literal 0s like `1 - 1`. The alternative is to use the fact that a pointer can be
40-
// constructed from literal 0, but this conflicts with `-Wzero-as-null-pointer-constant`.
41-
if (__zero != 0)
42-
__builtin_trap();
43-
}
34+
// If anything other than a literal 0 is provided, the behavior is undefined by the Standard.
35+
//
36+
// We handle this by making this function consteval and making the program ill-formed if
37+
// a value other than 0 is provided. This technically also accepts things that are not
38+
// literal 0s like `1 - 1`. The alternative is to use the fact that a pointer can be
39+
// constructed from literal 0, but this conflicts with `-Wzero-as-null-pointer-constant`.
40+
template <class _Tp, class = __enable_if_t<is_same_v<_Tp, int> > >
41+
_LIBCPP_HIDE_FROM_ABI consteval _CmpUnspecifiedParam(_Tp __zero) noexcept _LIBCPP_DIAGNOSE_ERROR(
42+
__zero != 0, "Only literal 0 is allowed as the operand of a comparison with one of the ordering types") {}
4443
};
4544

4645
class partial_ordering {

libcxx/include/__config

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -838,11 +838,11 @@ typedef __char32_t char32_t;
838838
# endif
839839

840840
// TODO: Remove this workaround once we drop support for Clang 16
841-
#if __has_warning("-Wc++23-extensions")
842-
# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED_CXX23_EXTENSION _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++23-extensions")
843-
#else
844-
# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED_CXX23_EXTENSION _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++2b-extensions")
845-
#endif
841+
# if __has_warning("-Wc++23-extensions")
842+
# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED_CXX23_EXTENSION _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++23-extensions")
843+
# else
844+
# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED_CXX23_EXTENSION _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++2b-extensions")
845+
# endif
846846

847847
// Clang modules take a significant compile time hit when pushing and popping diagnostics.
848848
// Since all the headers are marked as system headers in the modulemap, we can simply disable this
@@ -1453,6 +1453,12 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
14531453
# define _LIBCPP_DIAGNOSE_WARNING(...)
14541454
# endif
14551455

1456+
# if __has_attribute(__diagnose_if__)
1457+
# define _LIBCPP_DIAGNOSE_ERROR(...) __attribute__((__diagnose_if__(__VA_ARGS__, "error")))
1458+
# else
1459+
# define _LIBCPP_DIAGNOSE_ERROR(...)
1460+
# endif
1461+
14561462
// Use a function like macro to imply that it must be followed by a semicolon
14571463
# if __has_cpp_attribute(fallthrough)
14581464
# define _LIBCPP_FALLTHROUGH() [[fallthrough]]

libcxx/test/std/language.support/cmp/cmp.categories.pre/reject-other-than-literal-zero.verify.cpp

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,29 @@
2626

2727
#include "test_macros.h"
2828

29-
#define TEST_FAIL(v, op) \
29+
#define TEST_FAIL_INVALID_VALUE(v, op) \
3030
do { \
31-
void(v op 0L); \
32-
void(0L op v); \
3331
void(v op 1); \
3432
void(1 op v); \
33+
} while (false)
34+
35+
#define TEST_FAIL_INVALID_TYPE(v, op) \
36+
do { \
37+
void(v op 0L); \
38+
void(0L op v); \
39+
void(v op 0.0); \
40+
void(0.0 op v); \
3541
void(v op nullptr); \
3642
void(nullptr op v); \
3743
} while (false)
3844

45+
#define TEST_FAIL_NOT_COMPILE_TIME(v, op) \
46+
do { \
47+
int i = 0; \
48+
void(v op i); \
49+
void(i op v); \
50+
} while (false)
51+
3952
#define TEST_PASS(v, op) \
4053
do { \
4154
void(v op 0); \
@@ -46,13 +59,29 @@
4659

4760
template <typename T>
4861
void test_category(T v) {
49-
TEST_FAIL(v, ==); // expected-error 18 {{}}
50-
TEST_FAIL(v, !=); // expected-error 18 {{}}
51-
TEST_FAIL(v, <); // expected-error 18 {{}}
52-
TEST_FAIL(v, <=); // expected-error 18 {{}}
53-
TEST_FAIL(v, >); // expected-error 18 {{}}
54-
TEST_FAIL(v, >=); // expected-error 18 {{}}
55-
TEST_FAIL(v, <=>); // expected-error 18 {{}}
62+
TEST_FAIL_INVALID_TYPE(v, ==); // expected-error 18 {{invalid operands to binary expression}}
63+
TEST_FAIL_INVALID_TYPE(v, !=); // expected-error 18 {{invalid operands to binary expression}}
64+
TEST_FAIL_INVALID_TYPE(v, <); // expected-error 18 {{invalid operands to binary expression}}
65+
TEST_FAIL_INVALID_TYPE(v, <=); // expected-error 18 {{invalid operands to binary expression}}
66+
TEST_FAIL_INVALID_TYPE(v, >); // expected-error 18 {{invalid operands to binary expression}}
67+
TEST_FAIL_INVALID_TYPE(v, >=); // expected-error 18 {{invalid operands to binary expression}}
68+
TEST_FAIL_INVALID_TYPE(v, <=>); // expected-error 18 {{invalid operands to binary expression}}
69+
70+
TEST_FAIL_INVALID_VALUE(v, ==); // expected-error 6 {{Only literal 0 is allowed as the operand}}
71+
TEST_FAIL_INVALID_VALUE(v, !=); // expected-error 6 {{Only literal 0 is allowed as the operand}}
72+
TEST_FAIL_INVALID_VALUE(v, <); // expected-error 6 {{Only literal 0 is allowed as the operand}}
73+
TEST_FAIL_INVALID_VALUE(v, <=); // expected-error 6 {{Only literal 0 is allowed as the operand}}
74+
TEST_FAIL_INVALID_VALUE(v, >); // expected-error 6 {{Only literal 0 is allowed as the operand}}
75+
TEST_FAIL_INVALID_VALUE(v, >=); // expected-error 6 {{Only literal 0 is allowed as the operand}}
76+
TEST_FAIL_INVALID_VALUE(v, <=>); // expected-error 6 {{Only literal 0 is allowed as the operand}}
77+
78+
TEST_FAIL_NOT_COMPILE_TIME(v, ==); // expected-error 6 {{call to consteval function}}
79+
TEST_FAIL_NOT_COMPILE_TIME(v, !=); // expected-error 6 {{call to consteval function}}
80+
TEST_FAIL_NOT_COMPILE_TIME(v, <); // expected-error 6 {{call to consteval function}}
81+
TEST_FAIL_NOT_COMPILE_TIME(v, <=); // expected-error 6 {{call to consteval function}}
82+
TEST_FAIL_NOT_COMPILE_TIME(v, >); // expected-error 6 {{call to consteval function}}
83+
TEST_FAIL_NOT_COMPILE_TIME(v, >=); // expected-error 6 {{call to consteval function}}
84+
TEST_FAIL_NOT_COMPILE_TIME(v, <=>); // expected-error 6 {{call to consteval function}}
5685

5786
TEST_PASS(v, ==);
5887
TEST_PASS(v, !=);

0 commit comments

Comments
 (0)