1 // RUN: %clang_cc1 -std=c++17 %s -verify 2 // RUN: %clang_cc1 -std=c++20 %s -verify 3 // RUN: %clang_cc1 -std=c++20 %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++20 %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++20}} 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++20; 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++20}} 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