• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors \
2 // RUN:            -Wno-variadic-macros -Wno-c11-extensions
3 // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
4 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
5 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
6 // RUN: %clang_cc1 -std=c++2a -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
7 
8 #if __cplusplus < 201103L
9 #define static_assert(...) _Static_assert(__VA_ARGS__)
10 #endif
11 
12 namespace dr2026 { // dr2026: 11
13   template<int> struct X {};
14 
15   const int a = a + 1; // expected-warning {{uninitialized}} expected-note {{here}} expected-note 0-1{{outside its lifetime}}
16   X<a> xa; // expected-error {{constant expression}} expected-note {{initializer of 'a'}}
17 
18 #if __cplusplus >= 201103L
19   constexpr int b = b; // expected-error {{constant expression}} expected-note {{outside its lifetime}}
20   [[clang::require_constant_initialization]] int c = c; // expected-error {{constant initializer}} expected-note {{attribute}}
21 #if __cplusplus == 201103L
22   // expected-note@-2 {{read of non-const variable}} expected-note@-2 {{declared here}}
23 #else
24   // expected-note@-4 {{outside its lifetime}}
25 #endif
26 #endif
27 
28 #if __cplusplus > 201703L
29   constinit int d = d; // expected-error {{constant initializer}} expected-note {{outside its lifetime}} expected-note {{'constinit'}}
30 #endif
31 
f()32   void f() {
33     static const int e = e + 1; // expected-warning {{suspicious}} expected-note {{here}} expected-note 0-1{{outside its lifetime}}
34     X<e> xe; // expected-error {{constant expression}} expected-note {{initializer of 'e'}}
35 
36 #if __cplusplus >= 201103L
37     static constexpr int f = f; // expected-error {{constant expression}} expected-note {{outside its lifetime}}
38     [[clang::require_constant_initialization]] static int g = g; // expected-error {{constant initializer}} expected-note {{attribute}}
39 #if __cplusplus == 201103L
40     // expected-note@-2 {{read of non-const variable}} expected-note@-2 {{declared here}}
41 #else
42     // expected-note@-4 {{outside its lifetime}}
43 #endif
44 #endif
45 
46 #if __cplusplus > 201703L
47     static constinit int h = h; // expected-error {{constant initializer}} expected-note {{outside its lifetime}} expected-note {{'constinit'}}
48 #endif
49   }
50 }
51 
52 namespace dr2082 { // dr2082: 11
53   void test1(int x, int = sizeof(x)); // ok
54 #if __cplusplus >= 201103L
55   void test2(int x, int = decltype(x){}); // ok
56 #endif
57 }
58 
59 namespace dr2083 { // dr2083: partial
60 #if __cplusplus >= 201103L
non_const_mem_ptr()61   void non_const_mem_ptr() {
62     struct A {
63       int x;
64       int y;
65     };
66     constexpr A a = {1, 2};
67     struct B {
68       int A::*p;
69       constexpr int g() const {
70         // OK, not an odr-use of 'a'.
71         return a.*p;
72       };
73     };
74     static_assert(B{&A::x}.g() == 1, "");
75     static_assert(B{&A::y}.g() == 2, "");
76   }
77 #endif
78 
79   const int a = 1;
80   int b;
81   // Note, references only get special odr-use / constant initializxer
82   // treatment in C++11 onwards. We continue to apply that even after DR2083.
ref_to_non_const()83   void ref_to_non_const() {
84     int c;
85     const int &ra = a; // expected-note 0-1{{here}}
86     int &rb = b; // expected-note 0-1{{here}}
87     int &rc = c; // expected-note {{here}}
88     struct A {
89       int f() {
90         int a = ra;
91         int b = rb;
92 #if __cplusplus < 201103L
93         // expected-error@-3 {{in enclosing function}}
94         // expected-error@-3 {{in enclosing function}}
95 #endif
96         int c = rc; // expected-error {{in enclosing function}}
97         return a + b + c;
98       }
99     };
100   }
101 
102 #if __cplusplus >= 201103L
103   struct NoMut1 { int a, b; };
104   struct NoMut2 { NoMut1 m; };
105   struct NoMut3 : NoMut1 {
NoMut3dr2083::NoMut3106     constexpr NoMut3(int a, int b) : NoMut1{a, b} {}
107   };
108   struct Mut1 {
109     int a;
110     mutable int b;
111   };
112   struct Mut2 { Mut1 m; };
113   struct Mut3 : Mut1 {
Mut3dr2083::Mut3114     constexpr Mut3(int a, int b) : Mut1{a, b} {}
115   };
mutable_subobjects()116   void mutable_subobjects() {
117     constexpr NoMut1 nm1 = {1, 2};
118     constexpr NoMut2 nm2 = {1, 2};
119     constexpr NoMut3 nm3 = {1, 2};
120     constexpr Mut1 m1 = {1, 2}; // expected-note {{declared here}}
121     constexpr Mut2 m2 = {1, 2}; // expected-note {{declared here}}
122     constexpr Mut3 m3 = {1, 2}; // expected-note {{declared here}}
123     struct A {
124       void f() {
125         static_assert(nm1.a == 1, "");
126         static_assert(nm2.m.a == 1, "");
127         static_assert(nm3.a == 1, "");
128         // Can't even access a non-mutable member of a variable containing mutable fields.
129         static_assert(m1.a == 1, ""); // expected-error {{enclosing function}}
130         static_assert(m2.m.a == 1, ""); // expected-error {{enclosing function}}
131         static_assert(m3.a == 1, ""); // expected-error {{enclosing function}}
132       }
133     };
134   }
135 #endif
136 
ellipsis()137   void ellipsis() {
138     void ellipsis(...);
139     struct A {};
140     const int n = 0;
141 #if __cplusplus >= 201103L
142     constexpr
143 #endif
144       A a = {}; // expected-note {{here}}
145     struct B {
146       void f() {
147         ellipsis(n);
148         // Even though this is technically modelled as an lvalue-to-rvalue
149         // conversion, it calls a constructor and binds 'a' to a reference, so
150         // it results in an odr-use.
151         ellipsis(a); // expected-error {{enclosing function}}
152       }
153     };
154   }
155 
156 #if __cplusplus >= 201103L
volatile_lval()157   void volatile_lval() {
158     struct A { int n; };
159     constexpr A a = {0}; // expected-note {{here}}
160     struct B {
161       void f() {
162         // An lvalue-to-rvalue conversion of a volatile lvalue always results
163         // in odr-use.
164         int A::*p = &A::n;
165         int x = a.*p;
166         volatile int A::*q = p;
167         int y = a.*q; // expected-error {{enclosing function}}
168       }
169     };
170   }
171 #endif
172 
discarded_lval()173   void discarded_lval() {
174     struct A { int x; mutable int y; volatile int z; };
175     A a; // expected-note 1+{{here}}
176     int &r = a.x; // expected-note {{here}}
177     struct B {
178       void f() {
179         a.x; // expected-warning {{unused}}
180         a.*&A::x; // expected-warning {{unused}}
181         true ? a.x : a.y; // expected-warning {{unused}}
182         (void)a.x;
183         a.x, discarded_lval(); // expected-warning {{unused}}
184 #if 1 // FIXME: These errors are all incorrect; the above code is valid.
185       // expected-error@-6 {{enclosing function}}
186       // expected-error@-6 {{enclosing function}}
187       // expected-error@-6 2{{enclosing function}}
188       // expected-error@-6 {{enclosing function}}
189       // expected-error@-6 {{enclosing function}}
190 #endif
191 
192         // 'volatile' qualifier triggers an lvalue-to-rvalue conversion.
193         a.z; // expected-error {{enclosing function}}
194 #if __cplusplus < 201103L
195         // expected-warning@-2 {{assign into a variable}}
196 #endif
197 
198         // References always get "loaded" to determine what they reference,
199         // even if the result is discarded.
200         r; // expected-error {{enclosing function}} expected-warning {{unused}}
201       }
202     };
203   }
204 
205   namespace dr_example_1 {
206     extern int globx;
main()207     int main() {
208       const int &x = globx;
209       struct A {
210 #if __cplusplus < 201103L
211         // expected-error@+2 {{enclosing function}} expected-note@-3 {{here}}
212 #endif
213         const int *foo() { return &x; }
214       } a;
215       return *a.foo();
216     }
217   }
218 
219 #if __cplusplus >= 201103L
220   namespace dr_example_2 {
221     struct A {
222       int q;
Adr2083::dr_example_2::A223       constexpr A(int q) : q(q) {}
Adr2083::dr_example_2::A224       constexpr A(const A &a) : q(a.q * 2) {} // (note, not called)
225     };
226 
main(void)227     int main(void) {
228       constexpr A a(42);
229       constexpr int aq = a.q;
230       struct Q {
231         int foo() { return a.q; }
232       } q;
233       return q.foo();
234     }
235 
236     // Checking odr-use does not invent an lvalue-to-rvalue conversion (and
237     // hence copy construction) on the potential result variable.
238     struct B {
239       int b = 42;
Bdr2083::dr_example_2::B240       constexpr B() {}
241       constexpr B(const B&) = delete;
242     };
f()243     void f() {
244       constexpr B b;
245       struct Q {
246         constexpr int foo() const { return b.b; }
247       };
248       static_assert(Q().foo() == 42, "");
249     }
250   }
251 #endif
252 }
253 
254 namespace dr2094 { // dr2094: 5
255   struct A { int n; };
256   struct B { volatile int n; };
257   static_assert(__is_trivially_copyable(volatile int), "");
258   static_assert(__is_trivially_copyable(const volatile int), "");
259   static_assert(__is_trivially_copyable(const volatile int[]), "");
260   static_assert(__is_trivially_copyable(A), "");
261   static_assert(__is_trivially_copyable(volatile A), "");
262   static_assert(__is_trivially_copyable(const volatile A), "");
263   static_assert(__is_trivially_copyable(const volatile A[]), "");
264   static_assert(__is_trivially_copyable(B), "");
265 
266   static_assert(__is_trivially_constructible(A, A const&), "");
267   static_assert(__is_trivially_constructible(B, B const&), "");
268 
269   static_assert(__is_trivially_assignable(A, const A&), "");
270   static_assert(__is_trivially_assignable(B, const B&), "");
271 }
272