353 lines · cpp
1// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s -verify=expected,cxx98,cxx98-14,cxx98-11 -fexceptions -fcxx-exceptions -pedantic-errors2// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 %s -verify=expected,cxx98-14,cxx98-11,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors3// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++14 %s -verify=expected,cxx98-14,since-cxx14,since-cxx11,cxx14 -fexceptions -fcxx-exceptions -pedantic-errors4// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++17 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors5// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors6// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++23 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors7// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++2c %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors8 9#if __cplusplus == 199711L10#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)11// cxx98-error@-1 {{variadic macros are a C99 feature}}12#endif13 14namespace cwg705 { // cwg705: 2.715 namespace N {16 struct S {};17 void f(S); // #cwg705-f18 }19 20 void g() {21 N::S s;22 f(s); // ok23 (f)(s);24 // expected-error@-1 {{use of undeclared identifier 'f'}}25 // expected-note@#cwg705-f {{'N::f' declared here}}26 }27} // namespace cwg70528 29namespace cwg712 { // cwg712: partial30 void use(int);31 void f() {32 const int a = 0; // #cwg712-f-a33 struct X {34 void g(bool cond) {35 use(a);36 use((a));37 use(cond ? a : a);38 use((cond, a));39 // expected-warning@-1 {{left operand of comma operator has no effect}}40 41 (void)a;42 // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg712::f'}} FIXME43 // expected-note@#cwg712-f-a {{'a' declared here}}44 (void)(a);45 // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg712::f'}} FIXME46 // expected-note@#cwg712-f-a {{'a' declared here}}47 (void)(cond ? a : a); // #cwg712-ternary48 // expected-error@#cwg712-ternary {{reference to local variable 'a' declared in enclosing function 'cwg712::f'}} FIXME49 // expected-note@#cwg712-f-a {{'a' declared here}}50 // expected-error@#cwg712-ternary {{reference to local variable 'a' declared in enclosing function 'cwg712::f'}} FIXME51 // expected-note@#cwg712-f-a {{'a' declared here}}52 (void)(cond, a); // #cwg712-comma53 // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg712::f'}} FIXME54 // expected-note@#cwg712-f-a {{'a' declared here}}55 // expected-warning@#cwg712-comma {{left operand of comma operator has no effect}}56 }57 };58 }59 60#if __cplusplus >= 201103L61 void g() {62 struct A { int n; };63 constexpr A a = {0}; // #cwg712-g-a64 struct X {65 void g(bool cond) {66 use(a.n);67 use(a.*&A::n);68 69 (void)a.n;70 // since-cxx11-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg712::g'}} FIXME71 // since-cxx11-note@#cwg712-g-a {{'a' declared here}}72 (void)(a.*&A::n);73 // since-cxx11-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg712::g'}} FIXME74 // since-cxx11-note@#cwg712-g-a {{'a' declared here}}75 }76 };77 }78#endif79} // namespace cwg71280 81namespace cwg713 { // cwg713: 3.082template<typename T>83struct is_const {84 static const bool value = __is_const(T);85};86template<typename T>87struct is_volatile {88 static const bool value = __is_volatile(T);89};90 91static_assert(!is_const<void()const>::value, "");92static_assert(!is_const<void()const volatile>::value, "");93static_assert(!is_volatile<void()volatile>::value, "");94static_assert(!is_volatile<void()const volatile>::value, "");95#if __cplusplus >= 201103L96static_assert(!is_const<void()const&>::value, "");97static_assert(!is_volatile<void()volatile&>::value, "");98#endif99} // namespace cwg713100 101// cwg722 is in cwg722.cpp102 103namespace cwg727 { // cwg727: partial104 struct A {105 template<typename T> struct C; // #cwg727-C106 template<typename T> void f(); // #cwg727-f107 template<typename T> static int N; // #cwg727-N108 // cxx98-11-error@-1 {{variable templates are a C++14 extension}}109 110 template<> struct C<int>;111 template<> void f<int>();112 template<> int N<int>;113 114 template<typename T> struct C<T*>;115 template<typename T> static int N<T*>;116 117 struct B {118 template<> struct C<float>;119 // expected-error@-1 {{class template specialization of 'C' not in class 'A' or an enclosing namespace}}120 // expected-note@#cwg727-C {{explicitly specialized declaration is here}}121 template<> void f<float>();122 // expected-error@-1 {{no function template matches function template specialization 'f'}}123 template<> int N<float>;124 // expected-error@-1 {{variable template specialization of 'N' not in class 'A' or an enclosing namespace}}125 // expected-note@#cwg727-N {{explicitly specialized declaration is here}}126 127 template<typename T> struct C<T**>;128 // expected-error@-1 {{class template partial specialization of 'C' not in class 'A' or an enclosing namespace}}129 // expected-note@#cwg727-C {{explicitly specialized declaration is here}}130 template<typename T> static int N<T**>;131 // expected-error@-1 {{variable template partial specialization of 'N' not in class 'A' or an enclosing namespace}}132 // expected-note@#cwg727-N {{explicitly specialized declaration is here}}133 134 template<> struct A::C<double>;135 // expected-error@-1 {{non-friend class member 'C' cannot have a qualified name}}136 // expected-error@-2 {{class template specialization of 'C' not in class 'A' or an enclosing namespace}}137 // expected-note@#cwg727-C {{explicitly specialized declaration is here}}138 template<> void A::f<double>();139 // expected-error@-1 {{o function template matches function template specialization 'f'}}140 // expected-error@-2 {{non-friend class member 'f' cannot have a qualified name}}141 template<> int A::N<double>;142 // expected-error@-1 {{non-friend class member 'N' cannot have a qualified name}}143 // expected-error@-2 {{variable template specialization of 'N' not in class 'A' or an enclosing namespace}}144 // expected-note@#cwg727-N {{explicitly specialized declaration is here}}145 146 template<typename T> struct A::C<T***>;147 // expected-error@-1 {{non-friend class member 'C' cannot have a qualified name}}148 // expected-error@-2 {{class template partial specialization of 'C' not in class 'A' or an enclosing namespace}}149 // expected-note@#cwg727-C {{explicitly specialized declaration is here}}150 template<typename T> static int A::N<T***>;151 // expected-error@-1 {{non-friend class member 'N' cannot have a qualified name}}152 // expected-error@-2 {{variable template partial specialization of 'N' not in class 'A' or an enclosing namespace}}153 // expected-note@#cwg727-N {{explicitly specialized declaration is here}}154 };155 };156 157 template<> struct A::C<char>;158 template<> void A::f<char>();159 template<> int A::N<char>;160 161 template<typename T> struct A::C<T****>;162 template<typename T> int A::N<T****>;163 164 namespace C {165 template<> struct A::C<long>;166 // expected-error@-1 {{class template specialization of 'C' not in class 'A' or an enclosing namespace}}167 // expected-note@#cwg727-C {{explicitly specialized declaration is here}}168 template<> void A::f<long>();169 // expected-error@-1 {{function template specialization of 'f' not in class 'A' or an enclosing namespace}}170 // expected-note@#cwg727-f {{explicitly specialized declaration is here}}171 template<> int A::N<long>;172 // expected-error@-1 {{variable template specialization of 'N' not in class 'A' or an enclosing namespace}}173 // expected-note@#cwg727-N {{explicitly specialized declaration is here}}174 175 template<typename T> struct A::C<T*****>;176 // expected-error@-1 {{class template partial specialization of 'C' not in class 'A' or an enclosing namespace}}177 // expected-note@#cwg727-C {{explicitly specialized declaration is here}}178 template<typename T> int A::N<T*****>;179 // expected-error@-1 {{variable template partial specialization of 'N' not in class 'A' or an enclosing namespace}}180 // expected-note@#cwg727-N {{explicitly specialized declaration is here}}181 }182 183 template<typename>184 struct D {185 template<typename T> struct C { typename T::error e; };186 // expected-error@-1 {{type 'float' cannot be used prior to '::' because it has no members}}187 // expected-note@#cwg727-C-float {{in instantiation of template class 'cwg727::D<int>::C<float>' requested here}}188 template<typename T> void f() { T::error; }189 // expected-error@-1 {{type 'float' cannot be used prior to '::' because it has no members}}190 // expected-note@#cwg727-f-float {{in instantiation of function template specialization 'cwg727::D<int>::f<float>' requested here}}191 template<typename T> static const int N = T::error;192 // cxx98-11-error@-1 {{variable templates are a C++14 extension}}193 // expected-error@-2 {{type 'float' cannot be used prior to '::' because it has no members}}194 // expected-note@#cwg727-N-float {{in instantiation of static data member 'cwg727::D<int>::N<float>' requested here}}195 196 template<> struct C<int> {};197 template<> void f<int>() {}198 template<> const int N<int>;199 200 template<typename T> struct C<T*> {};201 template<typename T> static const int N<T*>;202 203 template<typename>204 struct E {205 template<> void f<void>() {}206 // expected-error@-1 {{no candidate function template was found for dependent member function template specialization}}207 };208 };209 210 void d(D<int> di) {211 D<int>::C<int>();212 di.f<int>();213 int a = D<int>::N<int>;214 215 D<int>::C<int*>();216 int b = D<int>::N<int*>;217 218 D<int>::C<float>(); // #cwg727-C-float219 di.f<float>(); // #cwg727-f-float220 int c = D<int>::N<float>; // #cwg727-N-float221 }222 223 namespace mixed_inner_outer_specialization {224#if __cplusplus >= 201103L225 template<int> struct A {226 template<int> constexpr int f() const { return 1; }227 template<> constexpr int f<0>() const { return 2; }228 };229 template<> template<int> constexpr int A<0>::f() const { return 3; }230 template<> template<> constexpr int A<0>::f<0>() const { return 4; }231 static_assert(A<1>().f<1>() == 1, "");232 static_assert(A<1>().f<0>() == 2, "");233 static_assert(A<0>().f<1>() == 3, "");234 static_assert(A<0>().f<0>() == 4, "");235#endif236 237#if __cplusplus >= 201402L238 template<int> struct B {239 template<int> static const int u = 1;240 template<> const int u<0> = 2; // #cwg727-u0241 242 // Note that in C++17 onwards, these are implicitly inline, and so the243 // initializer of v<0> is not instantiated with the declaration. In244 // C++14, v<0> is a non-defining declaration and its initializer is245 // instantiated with the class.246 template<int> static constexpr int v = 1;247 template<> constexpr int v<0> = 2; // #cwg727-v0248 249 template<int> static const inline int w = 1;250 // cxx14-error@-1 {{inline variables are a C++17 extension}}251 template<> const inline int w<0> = 2;252 // cxx14-error@-1 {{inline variables are a C++17 extension}}253 };254 255 template<> template<int> constexpr int B<0>::u = 3;256 template<> template<> constexpr int B<0>::u<0> = 4;257 // since-cxx14-error@-1 {{static data member 'u' already has an initializer}}258 // since-cxx14-note@#cwg727-u0 {{previous initialization is here}}259 260 template<> template<int> constexpr int B<0>::v = 3;261 template<> template<> constexpr int B<0>::v<0> = 4;262 // cxx14-error@-1 {{static data member 'v' already has an initializer}}263 // cxx14-note@#cwg727-v0 {{previous initialization is here}}264 265 template<> template<int> constexpr int B<0>::w = 3;266 template<> template<> constexpr int B<0>::w<0> = 4;267 268 static_assert(B<1>().u<1> == 1, "");269 static_assert(B<1>().u<0> == 2, "");270 static_assert(B<0>().u<1> == 3, "");271 272 static_assert(B<1>().v<1> == 1, "");273 static_assert(B<1>().v<0> == 2, "");274 static_assert(B<0>().v<1> == 3, "");275 static_assert(B<0>().v<0> == 4, "");276 // cxx14-error@-1 {{static assertion failed due to requirement 'cwg727::mixed_inner_outer_specialization::B<0>().v<0> == 4'}}277 // cxx14-note@-2 {{expression evaluates to '2 == 4'}}278 279 static_assert(B<1>().w<1> == 1, "");280 static_assert(B<1>().w<0> == 2, "");281 static_assert(B<0>().w<1> == 3, "");282 static_assert(B<0>().w<0> == 4, "");283#endif284 }285 286 template<typename T, typename U> struct Collision {287 // FIXME: Missing diagnostic for duplicate function explicit specialization declaration.288 template<typename> int f1();289 template<> int f1<T>();290 template<> int f1<U>();291 292 // FIXME: Missing diagnostic for fucntion redefinition!293 template<typename> int f2();294 template<> int f2<T>() {}295 template<> int f2<U>() {}296 297 template<typename> static int v1;298 // cxx98-11-error@-1 {{variable templates are a C++14 extension}}299 template<> int v1<T>; // #cwg727-v1-T300 template<> int v1<U>;301 // expected-error@-1 {{duplicate member 'v1'}}302 // expected-note@#cwg727-Collision-int-int {{in instantiation of template class 'cwg727::Collision<int, int>' requested here}}303 // expected-note@#cwg727-v1-T {{previous}}304 305 template<typename> static inline int v2;306 // cxx98-11-error@-1 {{variable templates are a C++14 extension}}307 // cxx98-14-error@-2 {{inline variables are a C++17 extension}}308 template<> inline int v2<T>; // #cwg727-v2-T309 // cxx98-14-error@-1 {{inline variables are a C++17 extension}}310 template<> inline int v2<U>;311 // cxx98-14-error@-1 {{inline variables are a C++17 extension}}312 // expected-error@-2 {{duplicate member 'v2'}}313 // expected-note@#cwg727-v2-T {{previous declaration is here}}314 315 // FIXME: Missing diagnostic for duplicate class explicit specialization.316 template<typename> struct S1;317 template<> struct S1<T>;318 template<> struct S1<U>;319 320 template<typename> struct S2;321 template<> struct S2<T> {}; // #cwg727-S2-T322 template<> struct S2<U> {};323 // expected-error@-1 {{redefinition of 'S2<int>'}}324 // expected-note@#cwg727-S2-T {{previous}}325 };326 Collision<int, int> c; // #cwg727-Collision-int-int327} // namespace cwg727328 329namespace cwg777 { // cwg777: 3.7330#if __cplusplus >= 201103L331template <typename... T>332void f(int i = 0, T ...args) {}333void ff() { f(); }334 335template <typename... T>336void g(int i = 0, T ...args, T ...args2) {}337 338template <typename... T>339void h(int i = 0, T ...args, int j = 1) {}340#endif341} // namespace cwg777342 343namespace cwg794 { // cwg794: 2.7344struct B {};345struct D : B {};346struct X {347 D d;348};349struct Y : X {};350B Y::*pm = &X::d;351// expected-error@-1 {{cannot initialize a variable of type 'B Y::*' with an rvalue of type 'D X::*': different classes ('Y' vs 'X')}}352} // namespace cwg794353