// RUN: %clang_cc1 -std=c++98 -pedantic-errors %s -verify=expected,cxx98-14 // RUN: %clang_cc1 -std=c++11 -pedantic-errors %s -verify=expected,cxx98-14 // RUN: %clang_cc1 -std=c++14 -pedantic-errors %s -verify=expected,cxx98-14 // RUN: %clang_cc1 -std=c++17 -pedantic-errors %s -verify=expected,since-cxx17 // RUN: %clang_cc1 -std=c++20 -pedantic-errors %s -verify=expected,since-cxx20,since-cxx17 // RUN: %clang_cc1 -std=c++23 -pedantic-errors %s -verify=expected,since-cxx20,since-cxx17 // RUN: %clang_cc1 -std=c++2c -pedantic-errors %s -verify=expected,since-cxx20,since-cxx17 namespace cwg2406 { // cwg2406: 5 #if __cplusplus >= 201703L void fallthrough(int n) { void g(), h(), i(); switch (n) { case 1: case 2: g(); [[fallthrough]]; case 3: // warning on fallthrough discouraged do { [[fallthrough]]; // since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}} } while (false); case 6: do { [[fallthrough]]; // since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}} } while (n); case 7: while (false) { [[fallthrough]]; // since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}} } case 5: h(); case 4: // implementation may warn on fallthrough i(); [[fallthrough]]; // since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}} } } #endif } // namespace cwg2406 namespace cwg2428 { // cwg2428: 19 #if __cplusplus >= 202002L template concept C [[deprecated]] = true; // #cwg2428-C template [[deprecated]] concept C2 = true; // since-cxx20-error@-1 {{expected unqualified-id}} template concept C3 = C; // since-cxx20-warning@-1 {{'C' is deprecated}} // since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} template // since-cxx20-warning@-1 {{'C' is deprecated}} // since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} requires C // since-cxx20-warning@-1 {{'C' is deprecated}} // since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} void f() { bool b = C; // since-cxx20-warning@-1 {{'C' is deprecated}} // since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} }; void g(C auto a) {}; // since-cxx20-warning@-1 {{'C' is deprecated}} // since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} template auto h() -> C auto { // since-cxx20-warning@-1 {{'C' is deprecated}} // since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} C auto foo = T(); // since-cxx20-warning@-1 {{'C' is deprecated}} // since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} C auto *bar = T(); // since-cxx20-warning@-1 {{'C' is deprecated}} // since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} C auto &baz = T(); // since-cxx20-warning@-1 {{'C' is deprecated}} // since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} C auto &&quux = T(); // since-cxx20-warning@-1 {{'C' is deprecated}} // since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} return foo; } #endif } // namespace cwg2428 namespace cwg2430 { // cwg2430: 2.7 struct S { S f(S s) { return s; } }; } // namespace cwg2430 namespace cwg2450 { // cwg2450: 18 #if __cplusplus >= 202302L struct S {int a;}; template void f(){} void test() { f<{0}>(); f<{.a= 0}>(); } #endif } // namespace cwg2450 namespace cwg2459 { // cwg2459: 18 #if __cplusplus >= 202302L struct A { constexpr A(float) {} }; template struct X {}; X<1> x; #endif } // namespace cwg2459 namespace cwg2445 { // cwg2445: 19 #if __cplusplus >= 202002L template constexpr bool F = false; template struct A { }; template bool operator==(T, A); template bool operator!=(A, U) { static_assert(F, "Isn't this less specialized?"); return false; } bool f(A ax, A ay) { return ay != ax; } template concept AlwaysTrue=true; template struct B { template bool operator==(const B&)const; }; template bool operator==(const B&,const B&) { static_assert(F, "Isn't this less specialized?"); return false; } bool g(B bx, B by) { return bx == by; } struct C{ template int operator+(T){return 0;} template void operator-(T){} }; template void operator+(C&&,T){} template int operator-(C&&,T){return 0;} void t(int* iptr){ int x1 = C{} + iptr; int x2 = C{} - iptr; } struct D{ template int operator+(T) volatile {return 1;} }; template void operator+(volatile D&,T) {} int foo(volatile D& d){ return d + 1; } #endif } // namespace cwg2445 namespace cwg2486 { // cwg2486: 4 c++17 struct C { void fn() throw(); }; static void call(C& c, void (C::*f)()) { (c.*f)(); } static void callNE(C& c, void (C::*f)() throw()) { // cxx98-14-warning@-1 {{mangled name of 'callNE' will change in C++17 due to non-throwing exception specification in function signature}} (c.*f)(); } void ref() { C c; call(c, &C::fn); // <= implicit cast removes noexcept callNE(c, &C::fn); } void (*p)(); void (*pp)() throw() = p; // since-cxx17-error@-1 {{cannot initialize a variable of type 'void (*)() throw()' with an lvalue of type 'void (*)()': different exception specifications}} struct S { typedef void (*p)(); operator p(); // #cwg2486-conv }; void (*q)() throw() = S(); // since-cxx17-error@-1 {{no viable conversion from 'S' to 'void (*)() throw()'}} // since-cxx17-note@#cwg2486-conv {{candidate function}} } // namespace cwg2486