| // RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors |
| // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors |
| // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors |
| // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors |
| // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors |
| // RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors |
| // RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors |
| |
| #if __cplusplus < 201103L |
| // expected-no-diagnostics |
| #endif |
| |
| namespace dr2516 { // dr2516: yes |
| // NB: reusing 1482 test |
| #if __cplusplus >= 201103L |
| template <typename T> struct S { |
| typedef char I; |
| }; |
| enum E2 : S<E2>::I { e }; |
| // expected-error@-1 {{use of undeclared identifier 'E2'}} |
| #endif |
| } // namespace dr2516 |
| |
| namespace dr2518 { // dr2518: 17 |
| |
| #if __cplusplus >= 201103L |
| template <class T> |
| void f(T t) { |
| if constexpr (sizeof(T) != sizeof(int)) { |
| #if __cplusplus < 201703L |
| // expected-error@-2 {{constexpr if is a C++17 extension}} |
| #endif |
| static_assert(false, "must be int-sized"); // expected-error {{must be int-size}} |
| } |
| } |
| |
| void g(char c) { |
| f(0); |
| f(c); // expected-note {{requested here}} |
| } |
| |
| template <typename Ty> |
| struct S { |
| static_assert(false); // expected-error {{static assertion failed}} |
| #if __cplusplus < 201703L |
| // expected-error@-2 {{'static_assert' with no message is a C++17 extension}} |
| #endif |
| }; |
| |
| template <> |
| struct S<int> {}; |
| |
| template <> |
| struct S<float> {}; |
| |
| int test_specialization() { |
| S<int> s1; |
| S<float> s2; |
| S<double> s3; // expected-note {{in instantiation of template class 'dr2518::S<double>' requested here}} |
| } |
| #endif |
| |
| } |
| |
| namespace dr2521 { // dr2521: 17 |
| #if __cplusplus >= 201103L |
| #pragma clang diagnostic push |
| #pragma clang diagnostic warning "-Wdeprecated-literal-operator" |
| long double operator"" _\u03C0___(long double); |
| // expected-warning@-1 {{identifier '_π___' preceded by whitespace in a literal operator declaration is deprecated}} |
| // expected-warning@-2 {{user-defined literal suffixes containing '__' are reserved}} |
| |
| template <char... Chars> decltype(sizeof 0) |
| operator"" _div(); |
| // expected-warning@-1 {{identifier '_div' preceded by whitespace in a literal operator declaration is deprecated}} |
| |
| using ::dr2521::operator"" _\u03C0___; |
| using ::dr2521::operator""_div; |
| // expected-warning@-2 {{identifier '_π___' preceded by whitespace in a literal operator declaration is deprecated}} |
| #pragma clang diagnostic pop |
| #endif |
| } // namespace dr2521 |
| |
| namespace dr2565 { // dr2565: 16 open |
| #if __cplusplus >= 202002L |
| template<typename T> |
| concept C = requires (typename T::type x) { |
| x + 1; |
| }; |
| static_assert(!C<int>); |
| |
| // Variant of this as reported in GH57487. |
| template<bool B> struct bool_constant |
| { static constexpr bool value = B; }; |
| |
| template<typename T> |
| using is_referenceable |
| = bool_constant<requires (T&) { true; }>; |
| |
| static_assert(!is_referenceable<void>::value); |
| static_assert(is_referenceable<int>::value); |
| |
| template<typename T, typename U> |
| concept TwoParams = requires (T *a, U b){ true;}; // #TPC |
| |
| template<typename T, typename U> |
| requires TwoParams<T, U> // #TPSREQ |
| struct TwoParamsStruct{}; |
| |
| using TPSU = TwoParamsStruct<void, void>; |
| // expected-error@-1{{constraints not satisfied for class template 'TwoParamsStruct'}} |
| // expected-note@#TPSREQ{{because 'TwoParams<void, void>' evaluated to false}} |
| // expected-note@#TPC{{because 'b' would be invalid: argument may not have 'void' type}} |
| |
| template<typename T, typename ...U> |
| concept Variadic = requires (U* ... a, T b){ true;}; // #VC |
| |
| template<typename T, typename ...U> |
| requires Variadic<T, U...> // #VSREQ |
| struct VariadicStruct{}; |
| |
| using VSU = VariadicStruct<void, int, char, double>; |
| // expected-error@-1{{constraints not satisfied for class template 'VariadicStruct'}} |
| // expected-note@#VSREQ{{because 'Variadic<void, int, char, double>' evaluated to false}} |
| // expected-note@#VC{{because 'b' would be invalid: argument may not have 'void' type}} |
| |
| template<typename T> |
| // expected-error@+1 {{unknown type name 'ErrorRequires'}} |
| concept ErrorRequires = requires (ErrorRequires auto x) { |
| x; |
| }; |
| static_assert(ErrorRequires<int>); |
| // expected-error@-1{{static assertion failed}} |
| // expected-note@-2{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} |
| |
| template<typename T> |
| // expected-error@+2 {{unknown type name 'NestedErrorInRequires'}} |
| concept NestedErrorInRequires = requires (T x) { |
| requires requires (NestedErrorInRequires auto y) { |
| y; |
| }; |
| }; |
| static_assert(NestedErrorInRequires<int>); |
| // expected-error@-1{{static assertion failed}} |
| // expected-note@-2{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} |
| |
| #endif |
| } |