// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify-directives -verify=expected,cxx98,cxx98-14,cxx98-11 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify-directives -verify=expected,cxx98-14,cxx98-11,since-cxx11 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++14 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify-directives -verify=expected,cxx98-14,since-cxx14,since-cxx11,cxx14 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++17 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify-directives -verify=expected,since-cxx17,since-cxx14,since-cxx11 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify-directives -verify=expected,since-cxx17,since-cxx14,since-cxx11 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++23 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify-directives -verify=expected,since-cxx17,since-cxx14,since-cxx11 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++2c %s -fexceptions -fcxx-exceptions -pedantic-errors -verify-directives -verify=expected,since-cxx17,since-cxx14,since-cxx11 #if __cplusplus == 199711L #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) // cxx98-error@-1 {{variadic macros are a C99 feature}} #endif namespace cwg705 { // cwg705: 2.7 namespace N { struct S {}; void f(S); // #cwg705-f } void g() { N::S s; f(s); // ok (f)(s); // expected-error@-1 {{use of undeclared identifier 'f'; did you mean 'N::f'?}} // expected-note@#cwg705-f {{'N::f' declared here}} } } // namespace cwg705 namespace cwg712 { // cwg712: partial void use(int); void f() { const int a = 0; // #cwg712-f-a struct X { void g(bool cond) { use(a); use((a)); use(cond ? a : a); (void)a; // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg712::f'}} FIXME // expected-note@#cwg712-f-a {{'a' declared here}} (void)(a); // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg712::f'}} FIXME // expected-note@#cwg712-f-a {{'a' declared here}} (void)(cond ? a : a); // #cwg712-ternary // expected-error@#cwg712-ternary {{reference to local variable 'a' declared in enclosing function 'cwg712::f'}} FIXME // expected-note@#cwg712-f-a {{'a' declared here}} // expected-error@#cwg712-ternary {{reference to local variable 'a' declared in enclosing function 'cwg712::f'}} FIXME // expected-note@#cwg712-f-a {{'a' declared here}} (void)(cond, a); // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg712::f'}} FIXME // expected-note@#cwg712-f-a {{'a' declared here}} // expected-warning@-3 {{left operand of comma operator has no effect}} use((cond, a)); // expected-warning@-1 {{left operand of comma operator has no effect}} } }; } #if __cplusplus >= 201103L void g() { struct A { int n; }; constexpr A a = {0}; // #cwg712-g-a struct X { void g(bool cond) { use(a.n); use(a.*&A::n); (void)a.n; // since-cxx11-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg712::g'}} FIXME // since-cxx11-note@#cwg712-g-a {{'a' declared here}} (void)(a.*&A::n); // since-cxx11-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg712::g'}} FIXME // since-cxx11-note@#cwg712-g-a {{'a' declared here}} } }; } #endif } // namespace cwg712 namespace cwg713 { // cwg713: 3.0 template struct is_const { static const bool value = __is_const(T); }; template struct is_volatile { static const bool value = __is_volatile(T); }; static_assert(!is_const::value, ""); static_assert(!is_const::value, ""); static_assert(!is_volatile::value, ""); static_assert(!is_volatile::value, ""); #if __cplusplus >= 201103L static_assert(!is_const::value, ""); static_assert(!is_volatile::value, ""); #endif } // namespace cwg713 // cwg722 is in cwg722.cpp namespace cwg727 { // cwg727: partial struct A { template struct C; // #cwg727-C template void f(); // #cwg727-f template static int N; // #cwg727-N // cxx98-11-error@-1 {{variable templates are a C++14 extension}} template<> struct C; template<> void f(); template<> int N; template struct C; template static int N; struct B { template<> struct C; // expected-error@-1 {{class template specialization of 'C' not in class 'A' or an enclosing namespace}} // expected-note@#cwg727-C {{explicitly specialized declaration is here}} template<> void f(); // expected-error@-1 {{no function template matches function template specialization 'f'}} template<> int N; // expected-error@-1 {{variable template specialization of 'N' not in class 'A' or an enclosing namespace}} // expected-note@#cwg727-N {{explicitly specialized declaration is here}} template struct C; // expected-error@-1 {{class template partial specialization of 'C' not in class 'A' or an enclosing namespace}} // expected-note@#cwg727-C {{explicitly specialized declaration is here}} template static int N; // expected-error@-1 {{variable template partial specialization of 'N' not in class 'A' or an enclosing namespace}} // expected-note@#cwg727-N {{explicitly specialized declaration is here}} template<> struct A::C; // expected-error@-1 {{non-friend class member 'C' cannot have a qualified name}} // expected-error@-2 {{class template specialization of 'C' not in class 'A' or an enclosing namespace}} // expected-note@#cwg727-C {{explicitly specialized declaration is here}} template<> void A::f(); // expected-error@-1 {{non-friend class member 'f' cannot have a qualified name}} // expected-error@-2 {{no function template matches function template specialization 'f'}} template<> int A::N; // expected-error@-1 {{non-friend class member 'N' cannot have a qualified name}} // expected-error@-2 {{variable template specialization of 'N' not in class 'A' or an enclosing namespace}} // expected-note@#cwg727-N {{explicitly specialized declaration is here}} template struct A::C; // expected-error@-1 {{non-friend class member 'C' cannot have a qualified name}} // expected-error@-2 {{class template partial specialization of 'C' not in class 'A' or an enclosing namespace}} // expected-note@#cwg727-C {{explicitly specialized declaration is here}} template static int A::N; // expected-error@-1 {{non-friend class member 'N' cannot have a qualified name}} // expected-error@-2 {{variable template partial specialization of 'N' not in class 'A' or an enclosing namespace}} // expected-note@#cwg727-N {{explicitly specialized declaration is here}} }; }; template<> struct A::C; template<> void A::f(); template<> int A::N; template struct A::C; template int A::N; namespace C { template<> struct A::C; // expected-error@-1 {{class template specialization of 'C' not in class 'A' or an enclosing namespace}} // expected-note@#cwg727-C {{explicitly specialized declaration is here}} template<> void A::f(); // expected-error@-1 {{function template specialization of 'f' not in class 'A' or an enclosing namespace}} // expected-note@#cwg727-f {{explicitly specialized declaration is here}} template<> int A::N; // expected-error@-1 {{variable template specialization of 'N' not in class 'A' or an enclosing namespace}} // expected-note@#cwg727-N {{explicitly specialized declaration is here}} template struct A::C; // expected-error@-1 {{class template partial specialization of 'C' not in class 'A' or an enclosing namespace}} // expected-note@#cwg727-C {{explicitly specialized declaration is here}} template int A::N; // expected-error@-1 {{variable template partial specialization of 'N' not in class 'A' or an enclosing namespace}} // expected-note@#cwg727-N {{explicitly specialized declaration is here}} } template struct D { template struct C { typename T::error e; }; // expected-error@-1 {{type 'float' cannot be used prior to '::' because it has no members}} // expected-note@#cwg727-C-float {{in instantiation of template class 'cwg727::D::C' requested here}} template void f() { T::error; } // expected-error@-1 {{type 'float' cannot be used prior to '::' because it has no members}} // expected-note@#cwg727-f-float {{in instantiation of function template specialization 'cwg727::D::f' requested here}} template<> struct C {}; template<> void f() {} template struct C {}; }; void d(D di) { D::C(); di.f(); D::C(); D::C(); // #cwg727-C-float } template void D::f(); // #cwg727-f-float #if __cplusplus >= 201402L template struct E { template static const int N = T::error; // since-cxx14-error@-1 {{type 'float' cannot be used prior to '::' because it has no members}} // since-cxx14-note@#cwg727-N-float {{in instantiation of static data member 'cwg727::E::N' requested here}} template<> const int N; template static const int N; }; void e() { int a = E::N; int b = E::N; int c = E::N; // #cwg727-N-float } #endif template struct F { template struct F2 { template<> void f() {} // expected-error@-1 {{no candidate function template was found for dependent member function template specialization}} }; }; namespace mixed_inner_outer_specialization { #if __cplusplus >= 201103L template struct A { template constexpr int f() const { return 1; } template<> constexpr int f<0>() const { return 2; } }; template<> template constexpr int A<0>::f() const { return 3; } template<> template<> constexpr int A<0>::f<0>() const { return 4; } static_assert(A<1>().f<1>() == 1, ""); static_assert(A<1>().f<0>() == 2, ""); static_assert(A<0>().f<1>() == 3, ""); static_assert(A<0>().f<0>() == 4, ""); #endif #if __cplusplus >= 201402L template struct B { template static const int u = 1; template<> const int u<0> = 2; // #cwg727-u0 // Note that in C++17 onwards, these are implicitly inline, and so the // initializer of v<0> is not instantiated with the declaration. In // C++14, v<0> is a non-defining declaration and its initializer is // instantiated with the class. template static constexpr int v = 1; template<> constexpr int v<0> = 2; // #cwg727-v0 template static const inline int w = 1; // cxx14-error@-1 {{inline variables are a C++17 extension}} template<> const inline int w<0> = 2; // cxx14-error@-1 {{inline variables are a C++17 extension}} }; template<> template constexpr int B<0>::u = 3; template<> template<> constexpr int B<0>::u<0> = 4; // since-cxx14-error@-1 {{static data member 'u' already has an initializer}} // since-cxx14-note@#cwg727-u0 {{previous initialization is here}} template<> template constexpr int B<0>::v = 3; template<> template<> constexpr int B<0>::v<0> = 4; // cxx14-error@-1 {{static data member 'v' already has an initializer}} // cxx14-note@#cwg727-v0 {{previous initialization is here}} template<> template constexpr int B<0>::w = 3; template<> template<> constexpr int B<0>::w<0> = 4; static_assert(B<1>().u<1> == 1, ""); static_assert(B<1>().u<0> == 2, ""); static_assert(B<0>().u<1> == 3, ""); static_assert(B<1>().v<1> == 1, ""); static_assert(B<1>().v<0> == 2, ""); static_assert(B<0>().v<1> == 3, ""); static_assert(B<0>().v<0> == 4, ""); // cxx14-error@-1 {{static assertion failed due to requirement 'cwg727::mixed_inner_outer_specialization::B<0>().v<0> == 4':}} // cxx14-note@-2 {{expression evaluates to '2 == 4'}} static_assert(B<1>().w<1> == 1, ""); static_assert(B<1>().w<0> == 2, ""); static_assert(B<0>().w<1> == 3, ""); static_assert(B<0>().w<0> == 4, ""); #endif } template struct Collision { // FIXME: Missing diagnostic for duplicate function explicit specialization declaration. template int f1(); template<> int f1(); template<> int f1(); // FIXME: Missing diagnostic for fucntion redefinition! template int f2(); template<> int f2() {} template<> int f2() {} #if __cplusplus >= 201402L template static int v1; template<> int v1; // #cwg727-v1-T template<> int v1; // since-cxx14-error@-1 {{duplicate member 'v1'}} // since-cxx14-note@#cwg727-Collision-int-int {{in instantiation of template class 'cwg727::Collision' requested here}} // since-cxx14-note@#cwg727-v1-T {{previous declaration is here}} #endif #if __cplusplus >= 201703L template static inline int v2; template<> inline int v2; // #cwg727-v2-T template<> inline int v2; // since-cxx17-error@-1 {{duplicate member 'v2'}} // since-cxx17-note@#cwg727-v2-T {{previous declaration is here}} #endif // FIXME: Missing diagnostic for duplicate class explicit specialization. template struct S1; template<> struct S1; template<> struct S1; template struct S2; template<> struct S2 {}; // #cwg727-S2-T template<> struct S2 {}; // expected-error@-1 {{redefinition of 'S2'}} // cxx98-11-note@#cwg727-Collision-int-int {{in instantiation of template class 'cwg727::Collision' requested here}} // expected-note@#cwg727-S2-T {{previous definition is here}} }; Collision c; // #cwg727-Collision-int-int } // namespace cwg727 namespace cwg730 { // cwg730: 2.7 struct A { template struct S {}; template void f() {} }; template <> struct A::S {}; template <> void A::f() {} } // namespace cwg730 namespace cwg743 { // cwg743: 3.1 #if __cplusplus >= 201103L struct S { using T = int; }; decltype(S())::T i; template using foo = typename decltype(T())::I; #endif } // namespace cwg743 namespace cwg777 { // cwg777: 3.7 #if __cplusplus >= 201103L template void f(int i = 0, T ...args) {} void ff() { f(); } template void g(int i = 0, T ...args, T ...args2) {} template void h(int i = 0, T ...args, int j = 1) {} #endif } // namespace cwg777 namespace cwg794 { // cwg794: 2.7 struct B {}; struct D : B {}; struct X { D d; }; struct Y : X {}; B Y::*pm = &X::d; // expected-error@-1 {{cannot initialize a variable of type 'B Y::*' with an rvalue of type 'D X::*': different classes ('Y' vs 'X')}} } // namespace cwg794