1 | // RUN: %clang_cc1 -std=c++17 %s -verify |
2 | // RUN: %clang_cc1 -std=c++2a %s -verify |
3 | // RUN: %clang_cc1 -std=c++2a %s -verify -Wc++17-compat -DCOMPAT |
4 | // |
5 | // RUN: %clang_cc1 -std=c++17 %s -E -o - | FileCheck %s --check-prefix=CXX17 |
6 | // RUN: %clang_cc1 -std=c++2a %s -E -o - | FileCheck %s --check-prefix=CXX20 |
7 | |
8 | namespace N { |
9 | |
10 | struct A {}; |
11 | void operator<=(A, A); |
12 | #if __cplusplus > 201703L |
13 | void operator<=>(A, A); |
14 | #ifdef COMPAT |
15 | // expected-warning@-2 {{'<=>' operator is incompatible with C++ standards before C++2a}} |
16 | #endif |
17 | #endif |
18 | |
19 | template<auto> struct X {}; |
20 | X<operator<=> |
21 | #if __cplusplus <= 201703L |
22 | // expected-warning@-2 {{'<=>' is a single token in C++2a; add a space to avoid a change in behavior}} |
23 | #else |
24 | > |
25 | #endif |
26 | #ifdef COMPAT |
27 | // expected-warning@-7 {{'<=>' operator is incompatible with C++ standards before C++2a}} |
28 | #endif |
29 | x; |
30 | } |
31 | |
32 | // <=> can be formed by pasting other comparison operators. |
33 | #if __cplusplus > 201703L |
34 | #define STR(x) #x |
35 | #define STR_EXPANDED(x) STR(x) |
36 | #define PASTE(x, y) x ## y |
37 | constexpr char a[] = STR_EXPANDED(PASTE(<, =>)); |
38 | constexpr char b[] = STR_EXPANDED(PASTE(<=, >)); |
39 | static_assert(__builtin_strcmp(a, "<=>") == 0); |
40 | static_assert(__builtin_strcmp(b, "<=>") == 0); |
41 | #endif |
42 | |
43 | // -E must not accidentally form a <=> token. |
44 | |
45 | // CXX17: preprocess1: < => |
46 | // CXX17: preprocess2: <=> |
47 | // CXX17: preprocess3: < => |
48 | // CXX17: preprocess4: <=>= |
49 | // CXX17: preprocess5: <=>> |
50 | // CXX17: preprocess6: <=>>= |
51 | // CXX17: preprocess7: <=> |
52 | // CXX17: preprocess8: <=>= |
53 | // |
54 | // CXX20: preprocess1: < => |
55 | // CXX20: preprocess2: <= > |
56 | // CXX20: preprocess3: < => |
57 | // CXX20: preprocess4: <= >= |
58 | // CXX20: preprocess5: <= >> |
59 | // CXX20: preprocess6: <= >>= |
60 | // CXX20: preprocess7: <=> |
61 | // CXX20: preprocess8: <=>= |
62 | |
63 | #define ID(x) x |
64 | [[some_vendor::some_attribute( // expected-warning {{unknown attribute}} |
65 | preprocess1: ID(<)ID(=>), |
66 | preprocess2: ID(<=)ID(>), |
67 | preprocess3: ID(<)ID(=)ID(>), |
68 | preprocess4: ID(<=)ID(>=), |
69 | preprocess5: ID(<=)ID(>>), |
70 | preprocess6: ID(<=)ID(>>=), |
71 | preprocess7: ID(<=>) // expected-warning 0-1{{'<=>'}} |
72 | preprocess8: ID(<=>=) // expected-warning 0-1{{'<=>'}} |
73 | )]]; |
74 | |