// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s -verify=expected,cxx98,cxx98-14,cxx98-11 -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 %s -verify=expected,cxx98-14,cxx98-11,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++14 %s -verify=expected,cxx98-14,since-cxx14,since-cxx11,cxx14 -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++17 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++23 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++2c %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors #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'}} // 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); use((cond, a)); // expected-warning@-1 {{left operand of comma operator has no effect}} (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); // #cwg712-comma // 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@#cwg712-comma {{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 {{o function template matches function template specialization 'f'}} // expected-error@-2 {{non-friend class member 'f' cannot have a qualified name}} 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 static const int N = T::error; // cxx98-11-error@-1 {{variable templates are a C++14 extension}} // expected-error@-2 {{type 'float' cannot be used prior to '::' because it has no members}} // expected-note@#cwg727-N-float {{in instantiation of static data member 'cwg727::D::N' requested here}} template<> struct C {}; template<> void f() {} template<> const int N; template struct C {}; template static const int N; template struct E { template<> void f() {} // expected-error@-1 {{no candidate function template was found for dependent member function template specialization}} }; }; void d(D di) { D::C(); di.f(); int a = D::N; D::C(); int b = D::N; D::C(); // #cwg727-C-float di.f(); // #cwg727-f-float int c = D::N; // #cwg727-N-float } 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() {} template static int v1; // cxx98-11-error@-1 {{variable templates are a C++14 extension}} template<> int v1; // #cwg727-v1-T template<> int v1; // expected-error@-1 {{duplicate member 'v1'}} // expected-note@#cwg727-Collision-int-int {{in instantiation of template class 'cwg727::Collision' requested here}} // expected-note@#cwg727-v1-T {{previous}} template static inline int v2; // cxx98-11-error@-1 {{variable templates are a C++14 extension}} // cxx98-14-error@-2 {{inline variables are a C++17 extension}} template<> inline int v2; // #cwg727-v2-T // cxx98-14-error@-1 {{inline variables are a C++17 extension}} template<> inline int v2; // cxx98-14-error@-1 {{inline variables are a C++17 extension}} // expected-error@-2 {{duplicate member 'v2'}} // expected-note@#cwg727-v2-T {{previous declaration is here}} // 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'}} // expected-note@#cwg727-S2-T {{previous}} }; Collision c; // #cwg727-Collision-int-int } // namespace cwg727 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