463 lines · cpp
1// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors2// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,cxx11 -fexceptions -fcxx-exceptions -pedantic-errors3// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors4// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors5// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors6// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors7// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -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 cwg2007 { // cwg2007: 3.415template<typename T> struct A { typename T::error e; };16template<typename T> struct B { };17B<A<void> > b1;18B<A<void> > b2 = b1;19int a = b2[0];20// cxx98-error@-1 {{type 'B<A<void> >' does not provide a subscript operator}}21// since-cxx11-error@-2 {{type 'B<A<void>>' does not provide a subscript operator}}22int b = __builtin_addressof(b2)->foo;23// cxx98-error@-1 {{no member named 'foo' in 'cwg2007::B<cwg2007::A<void> >'}}24// since-cxx11-error@-2 {{no member named 'foo' in 'cwg2007::B<cwg2007::A<void>>'}}25} // namespace cwg200726 27// cwg2009: na28 29namespace cwg2026 { // cwg2026: 1130 template<int> struct X {};31 32 const int a = a + 1; // #cwg2026-a33 // expected-warning@-1 {{variable 'a' is uninitialized when used within its own initialization}}34 X<a> xa; // #cwg2026-xa35 // cxx98-error@-1 {{non-type template argument of type 'int' is not an integral constant expression}}36 // cxx98-note@-2 {{initializer of 'a' is not a constant expression}}37 // cxx98-note@#cwg2026-a {{declared here}}38 // since-cxx11-error@#cwg2026-xa {{non-type template argument is not a constant expression}}39 // since-cxx11-note@#cwg2026-xa {{initializer of 'a' is not a constant expression}}40 // since-cxx11-note@#cwg2026-a {{declared here}}41 42#if __cplusplus >= 201103L43 constexpr int b = b;44 // since-cxx11-error@-1 {{constexpr variable 'b' must be initialized by a constant expression}}45 // since-cxx11-note@-2 {{read of object outside its lifetime is not allowed in a constant expression}}46 [[clang::require_constant_initialization]] int c = c;47 // since-cxx11-error@-1 {{variable does not have a constant initializer}}48 // since-cxx11-note@-2 {{required by 'require_constant_initialization' attribute here}}49 // cxx11-note@-3 {{read of non-const variable 'c' is not allowed in a constant expression}}50 // cxx11-note@-4 {{declared here}}51 // since-cxx14-note@-5 {{read of object outside its lifetime is not allowed in a constant expression}}52#endif53 54#if __cplusplus >= 202002L55 constinit int d = d;56 // since-cxx20-error@-1 {{variable does not have a constant initializer}}57 // since-cxx20-note@-2 {{required by 'constinit' specifier here}}58 // since-cxx20-note@-3 {{read of object outside its lifetime is not allowed in a constant expression}}59#endif60 61 void f() {62 static const int e = e + 1; // #cwg2026-e63 // expected-warning@-1 {{static variable 'e' is suspiciously used within its own initialization}}64 X<e> xe; // #cwg2026-xe65 // cxx98-error@-1 {{non-type template argument of type 'int' is not an integral constant expression}}66 // cxx98-note@-2 {{initializer of 'e' is not a constant expression}}67 // cxx98-note@#cwg2026-e {{declared here}}68 // since-cxx11-error@#cwg2026-xe {{non-type template argument is not a constant expression}}69 // since-cxx11-note@#cwg2026-xe {{initializer of 'e' is not a constant expression}}70 // since-cxx11-note@#cwg2026-e {{declared here}}71 72#if __cplusplus >= 201103L73 static constexpr int f = f;74 // since-cxx11-error@-1 {{constexpr variable 'f' must be initialized by a constant expression}}75 // since-cxx11-note@-2 {{read of object outside its lifetime is not allowed in a constant expression}}76 [[clang::require_constant_initialization]] static int g = g;77 // since-cxx11-error@-1 {{variable does not have a constant initializer}}78 // since-cxx11-note@-2 {{required by 'require_constant_initialization' attribute here}}79 // cxx11-note@-3 {{read of non-const variable 'g' is not allowed in a constant expression}}80 // cxx11-note@-4 {{declared here}}81 // since-cxx14-note@-5 {{read of object outside its lifetime is not allowed in a constant expression}}82#endif83 84#if __cplusplus >= 202002L85 static constinit int h = h;86 // since-cxx20-error@-1 {{variable does not have a constant initializer}}87 // since-cxx20-note@-2 {{required by 'constinit' specifier here}}88 // since-cxx20-note@-3 {{read of object outside its lifetime is not allowed in a constant expression}}89#endif90 }91} // namespace cwg202692 93namespace cwg2049 { // cwg2049: 1894#if __cplusplus >= 202302L95template <int* x = {}> struct X {};96X<> a;97X<nullptr> b;98static_assert(__is_same(decltype(a), decltype(b)));99#endif100} // namespace cwg2049101 102namespace cwg2061 { // cwg2061: 2.7103#if __cplusplus >= 201103L104 namespace A {105 inline namespace b {106 namespace C {107 // 'f' is the example from the DR. 'S' is an example where if we didn't108 // properly handle the two being the same, we would get an incomplete109 // type error during attempted instantiation.110 template<typename T> void f();111 template<typename T> struct S;112 }113 }114 }115 116 namespace A {117 namespace C {118 template<> void f<int>() { }119 template<> struct S<int> { };120 }121 }122 123 void use() {124 A::C::f<int>();125 A::C::S<int> s;126 }127#endif // C++11128} // namespace cwg2061129 130namespace cwg2076 { // cwg2076: 13131#if __cplusplus >= 201103L132 namespace std_example {133 struct A { A(int); };134 struct B { B(A); };135 B b{{0}};136 137 struct Params { int a; int b; };138 struct Foo {139 Foo(Params);140 };141 Foo foo{{1, 2}};142 }143 144 struct string_view {145 string_view(int); // not an aggregate146 };147 struct string {148 string(int); // not an aggregate149 operator string_view() const;150 };151 152 void foo(const string &); // #cwg2076-foo 153 void bar(string_view); // #cwg2076-bar154 155 void func(const string &arg) {156 // An argument in one set of braces is subject to user-defined conversions;157 // an argument in two sets of braces is not, but an identity conversion is158 // still OK.159 foo(arg);160 foo({arg});161 foo({{arg}});162 foo({{{arg}}});163 // since-cxx11-error@-1 {{no matching function}}164 // since-cxx11-note@#cwg2076-foo {{cannot convert initializer list}}165 bar(arg);166 bar({arg});167 bar({{arg}});168 // since-cxx11-error@-1 {{no matching function}}169 // since-cxx11-note@#cwg2076-bar {{cannot convert initializer list}}170 bar({{{arg}}});171 // since-cxx11-error@-1 {{no matching function}}172 // since-cxx11-note@#cwg2076-bar {{cannot convert initializer list}}173 }174#endif175} // namespace cwg2076176 177namespace cwg2082 { // cwg2082: 11178 void test1(int x, int = sizeof(x)); // ok179#if __cplusplus >= 201103L180 void test2(int x, int = decltype(x){}); // ok181#endif182} // namespace cwg2082183 184namespace cwg2083 { // cwg2083: partial185#if __cplusplus >= 201103L186 void non_const_mem_ptr() {187 struct A {188 int x;189 int y;190 };191 constexpr A a = {1, 2};192 struct B {193 int A::*p;194 constexpr int g() const {195 // OK, not an odr-use of 'a'.196 return a.*p;197 };198 };199 static_assert(B{&A::x}.g() == 1, "");200 static_assert(B{&A::y}.g() == 2, "");201 }202#endif203 204 const int a = 1;205 int b;206 // Note, references only get special odr-use / constant initializxer207 // treatment in C++11 onwards. We continue to apply that even after CWG2083.208 void ref_to_non_const() {209 int c;210 const int &ra = a; // #cwg2083-ra211 int &rb = b; // #cwg2083-rb212 int &rc = c; // #cwg2083-rc213 struct A {214 int f() {215 int a = ra;216 // cxx98-error@-1 {{reference to local variable 'ra' declared in enclosing function 'cwg2083::ref_to_non_const'}}217 // cxx98-note@#cwg2083-ra {{'ra' declared here}}218 int b = rb;219 // cxx98-error@-1 {{reference to local variable 'rb' declared in enclosing function 'cwg2083::ref_to_non_const'}}220 // cxx98-note@#cwg2083-rb {{'rb' declared here}}221 int c = rc;222 // expected-error@-1 {{reference to local variable 'rc' declared in enclosing function 'cwg2083::ref_to_non_const'}}223 // expected-note@#cwg2083-rc {{'rc' declared here}}224 return a + b + c;225 }226 };227 }228 229#if __cplusplus >= 201103L230 struct NoMut1 { int a, b; };231 struct NoMut2 { NoMut1 m; };232 struct NoMut3 : NoMut1 {233 constexpr NoMut3(int a, int b) : NoMut1{a, b} {}234 };235 struct Mut1 {236 int a;237 mutable int b;238 };239 struct Mut2 { Mut1 m; };240 struct Mut3 : Mut1 {241 constexpr Mut3(int a, int b) : Mut1{a, b} {}242 };243 void mutable_subobjects() {244 constexpr NoMut1 nm1 = {1, 2};245 constexpr NoMut2 nm2 = {1, 2};246 constexpr NoMut3 nm3 = {1, 2};247 constexpr Mut1 m1 = {1, 2}; // #cwg2083-m1248 constexpr Mut2 m2 = {1, 2}; // #cwg2083-m2249 constexpr Mut3 m3 = {1, 2}; // #cwg2083-m3250 struct A {251 void f() {252 static_assert(nm1.a == 1, "");253 static_assert(nm2.m.a == 1, "");254 static_assert(nm3.a == 1, "");255 // Can't even access a non-mutable member of a variable containing mutable fields.256 static_assert(m1.a == 1, "");257 // since-cxx11-error@-1 {{reference to local variable 'm1' declared in enclosing function 'cwg2083::mutable_subobjects'}}258 // since-cxx11-note@#cwg2083-m1 {{'m1' declared here}}259 static_assert(m2.m.a == 1, "");260 // since-cxx11-error@-1 {{reference to local variable 'm2' declared in enclosing function 'cwg2083::mutable_subobjects'}}261 // since-cxx11-note@#cwg2083-m2 {{'m2' declared here}}262 static_assert(m3.a == 1, "");263 // since-cxx11-error@-1 {{reference to local variable 'm3' declared in enclosing function 'cwg2083::mutable_subobjects'}}264 // since-cxx11-note@#cwg2083-m3 {{'m3' declared here}}265 }266 };267 }268#endif269 270 void ellipsis() {271 void ellipsis(...);272 struct A {};273 const int n = 0;274#if __cplusplus >= 201103L275 constexpr276#endif277 A a = {}; // #cwg2083-a278 struct B {279 void f() {280 ellipsis(n);281 // Even though this is technically modelled as an lvalue-to-rvalue282 // conversion, it calls a constructor and binds 'a' to a reference, so283 // it results in an odr-use.284 ellipsis(a);285 // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg2083::ellipsis'}}286 // expected-note@#cwg2083-a {{'a' declared here}}287 }288 };289 }290 291#if __cplusplus >= 201103L292 void volatile_lval() {293 struct A { int n; };294 constexpr A a = {0}; // #cwg2083-a2295 struct B {296 void f() {297 // An lvalue-to-rvalue conversion of a volatile lvalue always results298 // in odr-use.299 int A::*p = &A::n;300 int x = a.*p;301 volatile int A::*q = p;302 int y = a.*q;303 // since-cxx11-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg2083::volatile_lval'}}304 // since-cxx11-note@#cwg2083-a2 {{'a' declared here}}305 }306 };307 }308#endif309 310 void discarded_lval() {311 struct A { int x; mutable int y; volatile int z; };312 A a; // #cwg2083-a-3313 int &r = a.x; // #cwg2083-r314 struct B {315 void f() {316 // FIXME: We emit more errors than we should be. They are explicitly317 // marked below.318 a.x;319 // expected-warning@-1 {{expression result unused}}320 // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME321 // expected-note@#cwg2083-a-3 {{'a' declared here}}322 a.*&A::x;323 // expected-warning@-1 {{expression result unused}}324 // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME325 // expected-note@#cwg2083-a-3 {{'a' declared here}}326 true ? a.x : a.y; // #cwg2083-ternary327 // expected-warning@-1 {{expression result unused}}328 // expected-error@#cwg2083-ternary {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME329 // expected-note@#cwg2083-a-3 {{'a' declared here}}330 // expected-error@#cwg2083-ternary {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME331 // expected-note@#cwg2083-a-3 {{'a' declared here}}332 (void)a.x;333 // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME334 // expected-note@#cwg2083-a-3 {{'a' declared here}}335 a.x, discarded_lval();336 // expected-warning@-1 {{left operand of comma operator has no effect}}337 // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME338 // expected-note@#cwg2083-a-3 {{'a' declared here}}339 340 // 'volatile' qualifier triggers an lvalue-to-rvalue conversion.341 a.z;342 // cxx98-warning@-1 {{expression result unused; assign into a variable to force a volatile load}}343 // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}}344 // expected-note@#cwg2083-a-3 {{'a' declared here}}345 346 // References always get "loaded" to determine what they reference,347 // even if the result is discarded.348 r;349 // expected-warning@-1 {{expression result unused}}350 // expected-error@-2 {{reference to local variable 'r' declared in enclosing function 'cwg2083::discarded_lval'}}351 // expected-note@#cwg2083-r {{'r' declared here}}352 }353 };354 }355 356 namespace dr_example_1 {357 extern int globx;358 int main() {359 const int &x = globx; // #cwg2083-x360 struct A {361 const int *foo() { return &x; }362 // cxx98-error@-1 {{reference to local variable 'x' declared in enclosing function 'cwg2083::dr_example_1::main'}}363 // cxx98-note@#cwg2083-x {{'x' declared here}}364 } a;365 return *a.foo();366 }367 }368 369#if __cplusplus >= 201103L370 namespace dr_example_2 {371 struct A {372 int q;373 constexpr A(int q) : q(q) {}374 constexpr A(const A &a) : q(a.q * 2) {} // (note, not called)375 };376 377 int main(void) {378 constexpr A a(42);379 constexpr int aq = a.q;380 struct Q {381 int foo() { return a.q; }382 } q;383 return q.foo();384 }385 386 // Checking odr-use does not invent an lvalue-to-rvalue conversion (and387 // hence copy construction) on the potential result variable.388 struct B {389 int b = 42;390 constexpr B() {}391 constexpr B(const B&) = delete;392 };393 void f() {394 constexpr B b;395 struct Q {396 constexpr int foo() const { return b.b; }397 };398 static_assert(Q().foo() == 42, "");399 }400 }401#endif402} // namespace cwg2083403 404namespace cwg2084 { // cwg2084: 3.1405struct S {406 S();407};408union U {409 S s{}; // cxx98-error {{function definition does not declare parameters}}410} u;411} // namespace cwg2084412 413namespace cwg2091 { // cwg2091: 10414template<int &> struct X;415template<int &N> void f(X<N>&);416int n;417void g(X<n> &x) { f(x); }418 419namespace GH42233 {420enum E { I };421 422class AA { };423E EV[1] = {I};424 425template<class ENUM, const ENUM* const VALUES>426struct S427{428 template< class E, const E* const V>429 friend AA& operator<<( AA& os, const S<E,V>& e );430};431 432int f()433{434 S< E, EV > x;435 436 AA a;437 a << x;438 return 0;439}440} // namespace GH42233441} // namespace cwg2091 442 443namespace cwg2094 { // cwg2094: 5444 struct A { int n; };445 struct B { volatile int n; };446 static_assert(__is_trivially_copyable(volatile int), "");447 static_assert(__is_trivially_copyable(const volatile int), "");448 static_assert(__is_trivially_copyable(const volatile int[]), "");449 static_assert(__is_trivially_copyable(A), "");450 static_assert(__is_trivially_copyable(volatile A), "");451 static_assert(__is_trivially_copyable(const volatile A), "");452 static_assert(__is_trivially_copyable(const volatile A[]), "");453 static_assert(__is_trivially_copyable(B), "");454 455 static_assert(__is_trivially_constructible(A, A const&), "");456 static_assert(__is_trivially_constructible(B, B const&), "");457 458 static_assert(__is_trivially_assignable(A, const A&), "");459 static_assert(__is_trivially_assignable(B, const B&), "");460} // namespace cwg2094461 462// cwg2096: dup 2598463