1d358b2deSVlad Serebrennikov // RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors 2d358b2deSVlad Serebrennikov // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,cxx11 -fexceptions -fcxx-exceptions -pedantic-errors 3d358b2deSVlad Serebrennikov // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors 4d358b2deSVlad Serebrennikov // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors 5d358b2deSVlad Serebrennikov // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors 6d358b2deSVlad Serebrennikov // RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors 7d358b2deSVlad Serebrennikov // RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors 8d358b2deSVlad Serebrennikov 9d358b2deSVlad Serebrennikov #if __cplusplus == 199711L 10d358b2deSVlad Serebrennikov #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) 11d358b2deSVlad Serebrennikov // cxx98-error@-1 {{variadic macros are a C99 feature}} 12d358b2deSVlad Serebrennikov #endif 13d358b2deSVlad Serebrennikov 14d358b2deSVlad Serebrennikov namespace cwg2007 { // cwg2007: 3.4 15d358b2deSVlad Serebrennikov template<typename T> struct A { typename T::error e; }; 16d358b2deSVlad Serebrennikov template<typename T> struct B { }; 17d358b2deSVlad Serebrennikov B<A<void> > b1; 18d358b2deSVlad Serebrennikov B<A<void> > b2 = b1; 19d358b2deSVlad Serebrennikov int a = b2[0]; 20d358b2deSVlad Serebrennikov // cxx98-error@-1 {{type 'B<A<void> >' does not provide a subscript operator}} 21d358b2deSVlad Serebrennikov // since-cxx11-error@-2 {{type 'B<A<void>>' does not provide a subscript operator}} 22d358b2deSVlad Serebrennikov int b = __builtin_addressof(b2)->foo; 23d358b2deSVlad Serebrennikov // cxx98-error@-1 {{no member named 'foo' in 'cwg2007::B<cwg2007::A<void> >'}} 24d358b2deSVlad Serebrennikov // since-cxx11-error@-2 {{no member named 'foo' in 'cwg2007::B<cwg2007::A<void>>'}} 25463e61a0SVlad Serebrennikov } // namespace cwg2007 26d358b2deSVlad Serebrennikov 27d358b2deSVlad Serebrennikov // cwg2009: na 28d358b2deSVlad Serebrennikov 29d358b2deSVlad Serebrennikov namespace cwg2026 { // cwg2026: 11 30d358b2deSVlad Serebrennikov template<int> struct X {}; 31d358b2deSVlad Serebrennikov 32d358b2deSVlad Serebrennikov const int a = a + 1; // #cwg2026-a 33d358b2deSVlad Serebrennikov // expected-warning@-1 {{variable 'a' is uninitialized when used within its own initialization}} 34d358b2deSVlad Serebrennikov X<a> xa; // #cwg2026-xa 35d358b2deSVlad Serebrennikov // cxx98-error@-1 {{non-type template argument of type 'int' is not an integral constant expression}} 36d358b2deSVlad Serebrennikov // cxx98-note@-2 {{initializer of 'a' is not a constant expression}} 37d358b2deSVlad Serebrennikov // cxx98-note@#cwg2026-a {{declared here}} 38d358b2deSVlad Serebrennikov // since-cxx11-error@#cwg2026-xa {{non-type template argument is not a constant expression}} 39d358b2deSVlad Serebrennikov // since-cxx11-note@#cwg2026-xa {{initializer of 'a' is not a constant expression}} 40d358b2deSVlad Serebrennikov // since-cxx11-note@#cwg2026-a {{declared here}} 41d358b2deSVlad Serebrennikov 42d358b2deSVlad Serebrennikov #if __cplusplus >= 201103L 43d358b2deSVlad Serebrennikov constexpr int b = b; 44d358b2deSVlad Serebrennikov // since-cxx11-error@-1 {{constexpr variable 'b' must be initialized by a constant expression}} 45d358b2deSVlad Serebrennikov // since-cxx11-note@-2 {{read of object outside its lifetime is not allowed in a constant expression}} 46d358b2deSVlad Serebrennikov [[clang::require_constant_initialization]] int c = c; 47d358b2deSVlad Serebrennikov // since-cxx11-error@-1 {{variable does not have a constant initializer}} 48d358b2deSVlad Serebrennikov // since-cxx11-note@-2 {{required by 'require_constant_initialization' attribute here}} 49d358b2deSVlad Serebrennikov // cxx11-note@-3 {{read of non-const variable 'c' is not allowed in a constant expression}} 50d358b2deSVlad Serebrennikov // cxx11-note@-4 {{declared here}} 51d358b2deSVlad Serebrennikov // since-cxx14-note@-5 {{read of object outside its lifetime is not allowed in a constant expression}} 52d358b2deSVlad Serebrennikov #endif 53d358b2deSVlad Serebrennikov 54d358b2deSVlad Serebrennikov #if __cplusplus >= 202002L 55d358b2deSVlad Serebrennikov constinit int d = d; 56d358b2deSVlad Serebrennikov // since-cxx20-error@-1 {{variable does not have a constant initializer}} 57d358b2deSVlad Serebrennikov // since-cxx20-note@-2 {{required by 'constinit' specifier here}} 58d358b2deSVlad Serebrennikov // since-cxx20-note@-3 {{read of object outside its lifetime is not allowed in a constant expression}} 59d358b2deSVlad Serebrennikov #endif 60d358b2deSVlad Serebrennikov 61d358b2deSVlad Serebrennikov void f() { 62d358b2deSVlad Serebrennikov static const int e = e + 1; // #cwg2026-e 63d358b2deSVlad Serebrennikov // expected-warning@-1 {{static variable 'e' is suspiciously used within its own initialization}} 64d358b2deSVlad Serebrennikov X<e> xe; // #cwg2026-xe 65d358b2deSVlad Serebrennikov // cxx98-error@-1 {{non-type template argument of type 'int' is not an integral constant expression}} 66d358b2deSVlad Serebrennikov // cxx98-note@-2 {{initializer of 'e' is not a constant expression}} 67d358b2deSVlad Serebrennikov // cxx98-note@#cwg2026-e {{declared here}} 68d358b2deSVlad Serebrennikov // since-cxx11-error@#cwg2026-xe {{non-type template argument is not a constant expression}} 69d358b2deSVlad Serebrennikov // since-cxx11-note@#cwg2026-xe {{initializer of 'e' is not a constant expression}} 70d358b2deSVlad Serebrennikov // since-cxx11-note@#cwg2026-e {{declared here}} 71d358b2deSVlad Serebrennikov 72d358b2deSVlad Serebrennikov #if __cplusplus >= 201103L 73d358b2deSVlad Serebrennikov static constexpr int f = f; 74d358b2deSVlad Serebrennikov // since-cxx11-error@-1 {{constexpr variable 'f' must be initialized by a constant expression}} 75d358b2deSVlad Serebrennikov // since-cxx11-note@-2 {{read of object outside its lifetime is not allowed in a constant expression}} 76d358b2deSVlad Serebrennikov [[clang::require_constant_initialization]] static int g = g; 77d358b2deSVlad Serebrennikov // since-cxx11-error@-1 {{variable does not have a constant initializer}} 78d358b2deSVlad Serebrennikov // since-cxx11-note@-2 {{required by 'require_constant_initialization' attribute here}} 79d358b2deSVlad Serebrennikov // cxx11-note@-3 {{read of non-const variable 'g' is not allowed in a constant expression}} 80d358b2deSVlad Serebrennikov // cxx11-note@-4 {{declared here}} 81d358b2deSVlad Serebrennikov // since-cxx14-note@-5 {{read of object outside its lifetime is not allowed in a constant expression}} 82d358b2deSVlad Serebrennikov #endif 83d358b2deSVlad Serebrennikov 84d358b2deSVlad Serebrennikov #if __cplusplus >= 202002L 85d358b2deSVlad Serebrennikov static constinit int h = h; 86d358b2deSVlad Serebrennikov // since-cxx20-error@-1 {{variable does not have a constant initializer}} 87d358b2deSVlad Serebrennikov // since-cxx20-note@-2 {{required by 'constinit' specifier here}} 88d358b2deSVlad Serebrennikov // since-cxx20-note@-3 {{read of object outside its lifetime is not allowed in a constant expression}} 89d358b2deSVlad Serebrennikov #endif 90d358b2deSVlad Serebrennikov } 91463e61a0SVlad Serebrennikov } // namespace cwg2026 92d358b2deSVlad Serebrennikov 93d358b2deSVlad Serebrennikov namespace cwg2049 { // cwg2049: 18 94d358b2deSVlad Serebrennikov #if __cplusplus >= 202302L 95d358b2deSVlad Serebrennikov template <int* x = {}> struct X {}; 96d358b2deSVlad Serebrennikov X<> a; 97d358b2deSVlad Serebrennikov X<nullptr> b; 98d358b2deSVlad Serebrennikov static_assert(__is_same(decltype(a), decltype(b))); 99d358b2deSVlad Serebrennikov #endif 100463e61a0SVlad Serebrennikov } // namespace cwg2049 101d358b2deSVlad Serebrennikov 102*14ba3f9dSVlad Serebrennikov namespace cwg2061 { // cwg2061: 2.7 103d358b2deSVlad Serebrennikov #if __cplusplus >= 201103L 104d358b2deSVlad Serebrennikov namespace A { 105d358b2deSVlad Serebrennikov inline namespace b { 106d358b2deSVlad Serebrennikov namespace C { 107d358b2deSVlad Serebrennikov // 'f' is the example from the DR. 'S' is an example where if we didn't 108d358b2deSVlad Serebrennikov // properly handle the two being the same, we would get an incomplete 109d358b2deSVlad Serebrennikov // type error during attempted instantiation. 110d358b2deSVlad Serebrennikov template<typename T> void f(); 111d358b2deSVlad Serebrennikov template<typename T> struct S; 112d358b2deSVlad Serebrennikov } 113d358b2deSVlad Serebrennikov } 114d358b2deSVlad Serebrennikov } 115d358b2deSVlad Serebrennikov 116d358b2deSVlad Serebrennikov namespace A { 117d358b2deSVlad Serebrennikov namespace C { 118d358b2deSVlad Serebrennikov template<> void f<int>() { } 119d358b2deSVlad Serebrennikov template<> struct S<int> { }; 120d358b2deSVlad Serebrennikov } 121d358b2deSVlad Serebrennikov } 122d358b2deSVlad Serebrennikov 123d358b2deSVlad Serebrennikov void use() { 124d358b2deSVlad Serebrennikov A::C::f<int>(); 125d358b2deSVlad Serebrennikov A::C::S<int> s; 126d358b2deSVlad Serebrennikov } 127d358b2deSVlad Serebrennikov #endif // C++11 128463e61a0SVlad Serebrennikov } // namespace cwg2061 129d358b2deSVlad Serebrennikov 130d358b2deSVlad Serebrennikov namespace cwg2076 { // cwg2076: 13 131d358b2deSVlad Serebrennikov #if __cplusplus >= 201103L 132d358b2deSVlad Serebrennikov namespace std_example { 133d358b2deSVlad Serebrennikov struct A { A(int); }; 134d358b2deSVlad Serebrennikov struct B { B(A); }; 135d358b2deSVlad Serebrennikov B b{{0}}; 136d358b2deSVlad Serebrennikov 137d358b2deSVlad Serebrennikov struct Params { int a; int b; }; 138d358b2deSVlad Serebrennikov struct Foo { 139d358b2deSVlad Serebrennikov Foo(Params); 140d358b2deSVlad Serebrennikov }; 141d358b2deSVlad Serebrennikov Foo foo{{1, 2}}; 142d358b2deSVlad Serebrennikov } 143d358b2deSVlad Serebrennikov 144d358b2deSVlad Serebrennikov struct string_view { 145d358b2deSVlad Serebrennikov string_view(int); // not an aggregate 146d358b2deSVlad Serebrennikov }; 147d358b2deSVlad Serebrennikov struct string { 148d358b2deSVlad Serebrennikov string(int); // not an aggregate 149d358b2deSVlad Serebrennikov operator string_view() const; 150d358b2deSVlad Serebrennikov }; 151d358b2deSVlad Serebrennikov 152d358b2deSVlad Serebrennikov void foo(const string &); // #cwg2076-foo 153d358b2deSVlad Serebrennikov void bar(string_view); // #cwg2076-bar 154d358b2deSVlad Serebrennikov 155d358b2deSVlad Serebrennikov void func(const string &arg) { 156d358b2deSVlad Serebrennikov // An argument in one set of braces is subject to user-defined conversions; 157d358b2deSVlad Serebrennikov // an argument in two sets of braces is not, but an identity conversion is 158d358b2deSVlad Serebrennikov // still OK. 159d358b2deSVlad Serebrennikov foo(arg); 160d358b2deSVlad Serebrennikov foo({arg}); 161d358b2deSVlad Serebrennikov foo({{arg}}); 162d358b2deSVlad Serebrennikov foo({{{arg}}}); 163d358b2deSVlad Serebrennikov // since-cxx11-error@-1 {{no matching function}} 164d358b2deSVlad Serebrennikov // since-cxx11-note@#cwg2076-foo {{cannot convert initializer list}} 165d358b2deSVlad Serebrennikov bar(arg); 166d358b2deSVlad Serebrennikov bar({arg}); 167d358b2deSVlad Serebrennikov bar({{arg}}); 168d358b2deSVlad Serebrennikov // since-cxx11-error@-1 {{no matching function}} 169d358b2deSVlad Serebrennikov // since-cxx11-note@#cwg2076-bar {{cannot convert initializer list}} 170d358b2deSVlad Serebrennikov bar({{{arg}}}); 171d358b2deSVlad Serebrennikov // since-cxx11-error@-1 {{no matching function}} 172d358b2deSVlad Serebrennikov // since-cxx11-note@#cwg2076-bar {{cannot convert initializer list}} 173d358b2deSVlad Serebrennikov } 174d358b2deSVlad Serebrennikov #endif 175463e61a0SVlad Serebrennikov } // namespace cwg2076 176d358b2deSVlad Serebrennikov 177d358b2deSVlad Serebrennikov namespace cwg2082 { // cwg2082: 11 178d358b2deSVlad Serebrennikov void test1(int x, int = sizeof(x)); // ok 179d358b2deSVlad Serebrennikov #if __cplusplus >= 201103L 180d358b2deSVlad Serebrennikov void test2(int x, int = decltype(x){}); // ok 181d358b2deSVlad Serebrennikov #endif 182463e61a0SVlad Serebrennikov } // namespace cwg2082 183d358b2deSVlad Serebrennikov 184d358b2deSVlad Serebrennikov namespace cwg2083 { // cwg2083: partial 185d358b2deSVlad Serebrennikov #if __cplusplus >= 201103L 186d358b2deSVlad Serebrennikov void non_const_mem_ptr() { 187d358b2deSVlad Serebrennikov struct A { 188d358b2deSVlad Serebrennikov int x; 189d358b2deSVlad Serebrennikov int y; 190d358b2deSVlad Serebrennikov }; 191d358b2deSVlad Serebrennikov constexpr A a = {1, 2}; 192d358b2deSVlad Serebrennikov struct B { 193d358b2deSVlad Serebrennikov int A::*p; 194d358b2deSVlad Serebrennikov constexpr int g() const { 195d358b2deSVlad Serebrennikov // OK, not an odr-use of 'a'. 196d358b2deSVlad Serebrennikov return a.*p; 197d358b2deSVlad Serebrennikov }; 198d358b2deSVlad Serebrennikov }; 199d358b2deSVlad Serebrennikov static_assert(B{&A::x}.g() == 1, ""); 200d358b2deSVlad Serebrennikov static_assert(B{&A::y}.g() == 2, ""); 201d358b2deSVlad Serebrennikov } 202d358b2deSVlad Serebrennikov #endif 203d358b2deSVlad Serebrennikov 204d358b2deSVlad Serebrennikov const int a = 1; 205d358b2deSVlad Serebrennikov int b; 206d358b2deSVlad Serebrennikov // Note, references only get special odr-use / constant initializxer 207d358b2deSVlad Serebrennikov // treatment in C++11 onwards. We continue to apply that even after CWG2083. 208d358b2deSVlad Serebrennikov void ref_to_non_const() { 209d358b2deSVlad Serebrennikov int c; 210d358b2deSVlad Serebrennikov const int &ra = a; // #cwg2083-ra 211d358b2deSVlad Serebrennikov int &rb = b; // #cwg2083-rb 212d358b2deSVlad Serebrennikov int &rc = c; // #cwg2083-rc 213d358b2deSVlad Serebrennikov struct A { 214d358b2deSVlad Serebrennikov int f() { 215d358b2deSVlad Serebrennikov int a = ra; 216d358b2deSVlad Serebrennikov // cxx98-error@-1 {{reference to local variable 'ra' declared in enclosing function 'cwg2083::ref_to_non_const'}} 217d358b2deSVlad Serebrennikov // cxx98-note@#cwg2083-ra {{'ra' declared here}} 218d358b2deSVlad Serebrennikov int b = rb; 219d358b2deSVlad Serebrennikov // cxx98-error@-1 {{reference to local variable 'rb' declared in enclosing function 'cwg2083::ref_to_non_const'}} 220d358b2deSVlad Serebrennikov // cxx98-note@#cwg2083-rb {{'rb' declared here}} 221d358b2deSVlad Serebrennikov int c = rc; 222d358b2deSVlad Serebrennikov // expected-error@-1 {{reference to local variable 'rc' declared in enclosing function 'cwg2083::ref_to_non_const'}} 223d358b2deSVlad Serebrennikov // expected-note@#cwg2083-rc {{'rc' declared here}} 224d358b2deSVlad Serebrennikov return a + b + c; 225d358b2deSVlad Serebrennikov } 226d358b2deSVlad Serebrennikov }; 227d358b2deSVlad Serebrennikov } 228d358b2deSVlad Serebrennikov 229d358b2deSVlad Serebrennikov #if __cplusplus >= 201103L 230d358b2deSVlad Serebrennikov struct NoMut1 { int a, b; }; 231d358b2deSVlad Serebrennikov struct NoMut2 { NoMut1 m; }; 232d358b2deSVlad Serebrennikov struct NoMut3 : NoMut1 { 233d358b2deSVlad Serebrennikov constexpr NoMut3(int a, int b) : NoMut1{a, b} {} 234d358b2deSVlad Serebrennikov }; 235d358b2deSVlad Serebrennikov struct Mut1 { 236d358b2deSVlad Serebrennikov int a; 237d358b2deSVlad Serebrennikov mutable int b; 238d358b2deSVlad Serebrennikov }; 239d358b2deSVlad Serebrennikov struct Mut2 { Mut1 m; }; 240d358b2deSVlad Serebrennikov struct Mut3 : Mut1 { 241d358b2deSVlad Serebrennikov constexpr Mut3(int a, int b) : Mut1{a, b} {} 242d358b2deSVlad Serebrennikov }; 243d358b2deSVlad Serebrennikov void mutable_subobjects() { 244d358b2deSVlad Serebrennikov constexpr NoMut1 nm1 = {1, 2}; 245d358b2deSVlad Serebrennikov constexpr NoMut2 nm2 = {1, 2}; 246d358b2deSVlad Serebrennikov constexpr NoMut3 nm3 = {1, 2}; 247d358b2deSVlad Serebrennikov constexpr Mut1 m1 = {1, 2}; // #cwg2083-m1 248d358b2deSVlad Serebrennikov constexpr Mut2 m2 = {1, 2}; // #cwg2083-m2 249d358b2deSVlad Serebrennikov constexpr Mut3 m3 = {1, 2}; // #cwg2083-m3 250d358b2deSVlad Serebrennikov struct A { 251d358b2deSVlad Serebrennikov void f() { 252d358b2deSVlad Serebrennikov static_assert(nm1.a == 1, ""); 253d358b2deSVlad Serebrennikov static_assert(nm2.m.a == 1, ""); 254d358b2deSVlad Serebrennikov static_assert(nm3.a == 1, ""); 255d358b2deSVlad Serebrennikov // Can't even access a non-mutable member of a variable containing mutable fields. 256d358b2deSVlad Serebrennikov static_assert(m1.a == 1, ""); 257d358b2deSVlad Serebrennikov // since-cxx11-error@-1 {{reference to local variable 'm1' declared in enclosing function 'cwg2083::mutable_subobjects'}} 258d358b2deSVlad Serebrennikov // since-cxx11-note@#cwg2083-m1 {{'m1' declared here}} 259d358b2deSVlad Serebrennikov static_assert(m2.m.a == 1, ""); 260d358b2deSVlad Serebrennikov // since-cxx11-error@-1 {{reference to local variable 'm2' declared in enclosing function 'cwg2083::mutable_subobjects'}} 261d358b2deSVlad Serebrennikov // since-cxx11-note@#cwg2083-m2 {{'m2' declared here}} 262d358b2deSVlad Serebrennikov static_assert(m3.a == 1, ""); 263d358b2deSVlad Serebrennikov // since-cxx11-error@-1 {{reference to local variable 'm3' declared in enclosing function 'cwg2083::mutable_subobjects'}} 264d358b2deSVlad Serebrennikov // since-cxx11-note@#cwg2083-m3 {{'m3' declared here}} 265d358b2deSVlad Serebrennikov } 266d358b2deSVlad Serebrennikov }; 267d358b2deSVlad Serebrennikov } 268d358b2deSVlad Serebrennikov #endif 269d358b2deSVlad Serebrennikov 270d358b2deSVlad Serebrennikov void ellipsis() { 271d358b2deSVlad Serebrennikov void ellipsis(...); 272d358b2deSVlad Serebrennikov struct A {}; 273d358b2deSVlad Serebrennikov const int n = 0; 274d358b2deSVlad Serebrennikov #if __cplusplus >= 201103L 275d358b2deSVlad Serebrennikov constexpr 276d358b2deSVlad Serebrennikov #endif 277d358b2deSVlad Serebrennikov A a = {}; // #cwg2083-a 278d358b2deSVlad Serebrennikov struct B { 279d358b2deSVlad Serebrennikov void f() { 280d358b2deSVlad Serebrennikov ellipsis(n); 281d358b2deSVlad Serebrennikov // Even though this is technically modelled as an lvalue-to-rvalue 282d358b2deSVlad Serebrennikov // conversion, it calls a constructor and binds 'a' to a reference, so 283d358b2deSVlad Serebrennikov // it results in an odr-use. 284d358b2deSVlad Serebrennikov ellipsis(a); 285d358b2deSVlad Serebrennikov // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg2083::ellipsis'}} 286d358b2deSVlad Serebrennikov // expected-note@#cwg2083-a {{'a' declared here}} 287d358b2deSVlad Serebrennikov } 288d358b2deSVlad Serebrennikov }; 289d358b2deSVlad Serebrennikov } 290d358b2deSVlad Serebrennikov 291d358b2deSVlad Serebrennikov #if __cplusplus >= 201103L 292d358b2deSVlad Serebrennikov void volatile_lval() { 293d358b2deSVlad Serebrennikov struct A { int n; }; 294d358b2deSVlad Serebrennikov constexpr A a = {0}; // #cwg2083-a2 295d358b2deSVlad Serebrennikov struct B { 296d358b2deSVlad Serebrennikov void f() { 297d358b2deSVlad Serebrennikov // An lvalue-to-rvalue conversion of a volatile lvalue always results 298d358b2deSVlad Serebrennikov // in odr-use. 299d358b2deSVlad Serebrennikov int A::*p = &A::n; 300d358b2deSVlad Serebrennikov int x = a.*p; 301d358b2deSVlad Serebrennikov volatile int A::*q = p; 302d358b2deSVlad Serebrennikov int y = a.*q; 303d358b2deSVlad Serebrennikov // since-cxx11-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg2083::volatile_lval'}} 304d358b2deSVlad Serebrennikov // since-cxx11-note@#cwg2083-a2 {{'a' declared here}} 305d358b2deSVlad Serebrennikov } 306d358b2deSVlad Serebrennikov }; 307d358b2deSVlad Serebrennikov } 308d358b2deSVlad Serebrennikov #endif 309d358b2deSVlad Serebrennikov 310d358b2deSVlad Serebrennikov void discarded_lval() { 311d358b2deSVlad Serebrennikov struct A { int x; mutable int y; volatile int z; }; 312d358b2deSVlad Serebrennikov A a; // #cwg2083-a-3 313d358b2deSVlad Serebrennikov int &r = a.x; // #cwg2083-r 314d358b2deSVlad Serebrennikov struct B { 315d358b2deSVlad Serebrennikov void f() { 3163f222f3bSc8ef // FIXME: We emit more errors than we should be. They are explicitly 3173f222f3bSc8ef // marked below. 318d358b2deSVlad Serebrennikov a.x; 319d358b2deSVlad Serebrennikov // expected-warning@-1 {{expression result unused}} 320d358b2deSVlad Serebrennikov // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME 321d358b2deSVlad Serebrennikov // expected-note@#cwg2083-a-3 {{'a' declared here}} 322d358b2deSVlad Serebrennikov a.*&A::x; 323d358b2deSVlad Serebrennikov // expected-warning@-1 {{expression result unused}} 324d358b2deSVlad Serebrennikov // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME 325d358b2deSVlad Serebrennikov // expected-note@#cwg2083-a-3 {{'a' declared here}} 326d358b2deSVlad Serebrennikov true ? a.x : a.y; // #cwg2083-ternary 327d358b2deSVlad Serebrennikov // expected-warning@-1 {{expression result unused}} 328d358b2deSVlad Serebrennikov // expected-error@#cwg2083-ternary {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME 329d358b2deSVlad Serebrennikov // expected-note@#cwg2083-a-3 {{'a' declared here}} 330d358b2deSVlad Serebrennikov // expected-error@#cwg2083-ternary {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME 331d358b2deSVlad Serebrennikov // expected-note@#cwg2083-a-3 {{'a' declared here}} 332d358b2deSVlad Serebrennikov (void)a.x; 333d358b2deSVlad Serebrennikov // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME 334d358b2deSVlad Serebrennikov // expected-note@#cwg2083-a-3 {{'a' declared here}} 335d358b2deSVlad Serebrennikov a.x, discarded_lval(); 336d358b2deSVlad Serebrennikov // expected-warning@-1 {{left operand of comma operator has no effect}} 337d358b2deSVlad Serebrennikov // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME 338d358b2deSVlad Serebrennikov // expected-note@#cwg2083-a-3 {{'a' declared here}} 339d358b2deSVlad Serebrennikov 340d358b2deSVlad Serebrennikov // 'volatile' qualifier triggers an lvalue-to-rvalue conversion. 341d358b2deSVlad Serebrennikov a.z; 342d358b2deSVlad Serebrennikov // cxx98-warning@-1 {{expression result unused; assign into a variable to force a volatile load}} 343d358b2deSVlad Serebrennikov // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} 344d358b2deSVlad Serebrennikov // expected-note@#cwg2083-a-3 {{'a' declared here}} 345d358b2deSVlad Serebrennikov 346d358b2deSVlad Serebrennikov // References always get "loaded" to determine what they reference, 347d358b2deSVlad Serebrennikov // even if the result is discarded. 348d358b2deSVlad Serebrennikov r; 349d358b2deSVlad Serebrennikov // expected-warning@-1 {{expression result unused}} 350d358b2deSVlad Serebrennikov // expected-error@-2 {{reference to local variable 'r' declared in enclosing function 'cwg2083::discarded_lval'}} 351d358b2deSVlad Serebrennikov // expected-note@#cwg2083-r {{'r' declared here}} 352d358b2deSVlad Serebrennikov } 353d358b2deSVlad Serebrennikov }; 354d358b2deSVlad Serebrennikov } 355d358b2deSVlad Serebrennikov 356d358b2deSVlad Serebrennikov namespace dr_example_1 { 357d358b2deSVlad Serebrennikov extern int globx; 358d358b2deSVlad Serebrennikov int main() { 359d358b2deSVlad Serebrennikov const int &x = globx; // #cwg2083-x 360d358b2deSVlad Serebrennikov struct A { 361d358b2deSVlad Serebrennikov const int *foo() { return &x; } 362d358b2deSVlad Serebrennikov // cxx98-error@-1 {{reference to local variable 'x' declared in enclosing function 'cwg2083::dr_example_1::main'}} 363d358b2deSVlad Serebrennikov // cxx98-note@#cwg2083-x {{'x' declared here}} 364d358b2deSVlad Serebrennikov } a; 365d358b2deSVlad Serebrennikov return *a.foo(); 366d358b2deSVlad Serebrennikov } 367d358b2deSVlad Serebrennikov } 368d358b2deSVlad Serebrennikov 369d358b2deSVlad Serebrennikov #if __cplusplus >= 201103L 370d358b2deSVlad Serebrennikov namespace dr_example_2 { 371d358b2deSVlad Serebrennikov struct A { 372d358b2deSVlad Serebrennikov int q; 373d358b2deSVlad Serebrennikov constexpr A(int q) : q(q) {} 374d358b2deSVlad Serebrennikov constexpr A(const A &a) : q(a.q * 2) {} // (note, not called) 375d358b2deSVlad Serebrennikov }; 376d358b2deSVlad Serebrennikov 377d358b2deSVlad Serebrennikov int main(void) { 378d358b2deSVlad Serebrennikov constexpr A a(42); 379d358b2deSVlad Serebrennikov constexpr int aq = a.q; 380d358b2deSVlad Serebrennikov struct Q { 381d358b2deSVlad Serebrennikov int foo() { return a.q; } 382d358b2deSVlad Serebrennikov } q; 383d358b2deSVlad Serebrennikov return q.foo(); 384d358b2deSVlad Serebrennikov } 385d358b2deSVlad Serebrennikov 386d358b2deSVlad Serebrennikov // Checking odr-use does not invent an lvalue-to-rvalue conversion (and 387d358b2deSVlad Serebrennikov // hence copy construction) on the potential result variable. 388d358b2deSVlad Serebrennikov struct B { 389d358b2deSVlad Serebrennikov int b = 42; 390d358b2deSVlad Serebrennikov constexpr B() {} 391d358b2deSVlad Serebrennikov constexpr B(const B&) = delete; 392d358b2deSVlad Serebrennikov }; 393d358b2deSVlad Serebrennikov void f() { 394d358b2deSVlad Serebrennikov constexpr B b; 395d358b2deSVlad Serebrennikov struct Q { 396d358b2deSVlad Serebrennikov constexpr int foo() const { return b.b; } 397d358b2deSVlad Serebrennikov }; 398d358b2deSVlad Serebrennikov static_assert(Q().foo() == 42, ""); 399d358b2deSVlad Serebrennikov } 400d358b2deSVlad Serebrennikov } 401d358b2deSVlad Serebrennikov #endif 402463e61a0SVlad Serebrennikov } // namespace cwg2083 403d358b2deSVlad Serebrennikov 4047417b4cdSVlad Serebrennikov namespace cwg2091 { // cwg2091: 10 4051fdc553eSVlad Serebrennikov template<int &> struct X; 4061fdc553eSVlad Serebrennikov template<int &N> void f(X<N>&); 4071fdc553eSVlad Serebrennikov int n; 4081fdc553eSVlad Serebrennikov void g(X<n> &x) { f(x); } 4097417b4cdSVlad Serebrennikov 4107417b4cdSVlad Serebrennikov namespace GH42233 { 4117417b4cdSVlad Serebrennikov enum E { I }; 4127417b4cdSVlad Serebrennikov 4137417b4cdSVlad Serebrennikov class AA { }; 4147417b4cdSVlad Serebrennikov E EV[1] = {I}; 4157417b4cdSVlad Serebrennikov 4167417b4cdSVlad Serebrennikov template<class ENUM, const ENUM* const VALUES> 4177417b4cdSVlad Serebrennikov struct S 4187417b4cdSVlad Serebrennikov { 4197417b4cdSVlad Serebrennikov template< class E, const E* const V> 4207417b4cdSVlad Serebrennikov friend AA& operator<<( AA& os, const S<E,V>& e ); 4217417b4cdSVlad Serebrennikov }; 4227417b4cdSVlad Serebrennikov 4237417b4cdSVlad Serebrennikov int f() 4247417b4cdSVlad Serebrennikov { 4257417b4cdSVlad Serebrennikov S< E, EV > x; 4267417b4cdSVlad Serebrennikov 4277417b4cdSVlad Serebrennikov AA a; 4287417b4cdSVlad Serebrennikov a << x; 4297417b4cdSVlad Serebrennikov return 0; 4307417b4cdSVlad Serebrennikov } 4317417b4cdSVlad Serebrennikov } // namespace GH42233 4321fdc553eSVlad Serebrennikov } // namespace cwg2091 4331fdc553eSVlad Serebrennikov 434d358b2deSVlad Serebrennikov namespace cwg2094 { // cwg2094: 5 435d358b2deSVlad Serebrennikov struct A { int n; }; 436d358b2deSVlad Serebrennikov struct B { volatile int n; }; 437d358b2deSVlad Serebrennikov static_assert(__is_trivially_copyable(volatile int), ""); 438d358b2deSVlad Serebrennikov static_assert(__is_trivially_copyable(const volatile int), ""); 439d358b2deSVlad Serebrennikov static_assert(__is_trivially_copyable(const volatile int[]), ""); 440d358b2deSVlad Serebrennikov static_assert(__is_trivially_copyable(A), ""); 441d358b2deSVlad Serebrennikov static_assert(__is_trivially_copyable(volatile A), ""); 442d358b2deSVlad Serebrennikov static_assert(__is_trivially_copyable(const volatile A), ""); 443d358b2deSVlad Serebrennikov static_assert(__is_trivially_copyable(const volatile A[]), ""); 444d358b2deSVlad Serebrennikov static_assert(__is_trivially_copyable(B), ""); 445d358b2deSVlad Serebrennikov 446d358b2deSVlad Serebrennikov static_assert(__is_trivially_constructible(A, A const&), ""); 447d358b2deSVlad Serebrennikov static_assert(__is_trivially_constructible(B, B const&), ""); 448d358b2deSVlad Serebrennikov 449d358b2deSVlad Serebrennikov static_assert(__is_trivially_assignable(A, const A&), ""); 450d358b2deSVlad Serebrennikov static_assert(__is_trivially_assignable(B, const B&), ""); 451463e61a0SVlad Serebrennikov } // namespace cwg2094 452d358b2deSVlad Serebrennikov 453d358b2deSVlad Serebrennikov // cwg2096: dup 2598 454