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++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
6 
7 #if __cplusplus < 201103L
8 #define static_assert(...) _Static_assert(__VA_ARGS__)
9 #endif
10 
11 namespace dr2083 { // dr2083: partial
12 #if __cplusplus >= 201103L
non_const_mem_ptr()13   void non_const_mem_ptr() {
14     struct A {
15       int x;
16       int y;
17     };
18     constexpr A a = {1, 2};
19     struct B {
20       int A::*p;
21       constexpr int g() const {
22         // OK, not an odr-use of 'a'.
23         return a.*p;
24       };
25     };
26     static_assert(B{&A::x}.g() == 1, "");
27     static_assert(B{&A::y}.g() == 2, "");
28   }
29 #endif
30 
31   const int a = 1;
32   int b;
33   // Note, references only get special odr-use / constant initializxer
34   // treatment in C++11 onwards. We continue to apply that even after DR2083.
ref_to_non_const()35   void ref_to_non_const() {
36     int c;
37     const int &ra = a; // expected-note 0-1{{here}}
38     int &rb = b; // expected-note 0-1{{here}}
39     int &rc = c; // expected-note {{here}}
40     struct A {
41       int f() {
42         int a = ra;
43         int b = rb;
44 #if __cplusplus < 201103L
45         // expected-error@-3 {{in enclosing function}}
46         // expected-error@-3 {{in enclosing function}}
47 #endif
48         int c = rc; // expected-error {{in enclosing function}}
49         return a + b + c;
50       }
51     };
52   }
53 
54 #if __cplusplus >= 201103L
55   struct NoMut1 { int a, b; };
56   struct NoMut2 { NoMut1 m; };
57   struct NoMut3 : NoMut1 {
NoMut3dr2083::NoMut358     constexpr NoMut3(int a, int b) : NoMut1{a, b} {}
59   };
60   struct Mut1 {
61     int a;
62     mutable int b;
63   };
64   struct Mut2 { Mut1 m; };
65   struct Mut3 : Mut1 {
Mut3dr2083::Mut366     constexpr Mut3(int a, int b) : Mut1{a, b} {}
67   };
mutable_subobjects()68   void mutable_subobjects() {
69     constexpr NoMut1 nm1 = {1, 2};
70     constexpr NoMut2 nm2 = {1, 2};
71     constexpr NoMut3 nm3 = {1, 2};
72     constexpr Mut1 m1 = {1, 2}; // expected-note {{declared here}}
73     constexpr Mut2 m2 = {1, 2}; // expected-note {{declared here}}
74     constexpr Mut3 m3 = {1, 2}; // expected-note {{declared here}}
75     struct A {
76       void f() {
77         static_assert(nm1.a == 1, "");
78         static_assert(nm2.m.a == 1, "");
79         static_assert(nm3.a == 1, "");
80         // Can't even access a non-mutable member of a variable containing mutable fields.
81         static_assert(m1.a == 1, ""); // expected-error {{enclosing function}}
82         static_assert(m2.m.a == 1, ""); // expected-error {{enclosing function}}
83         static_assert(m3.a == 1, ""); // expected-error {{enclosing function}}
84       }
85     };
86   }
87 #endif
88 
ellipsis()89   void ellipsis() {
90     void ellipsis(...);
91     struct A {};
92     const int n = 0;
93 #if __cplusplus >= 201103L
94     constexpr
95 #endif
96       A a = {}; // expected-note {{here}}
97     struct B {
98       void f() {
99         ellipsis(n);
100         // Even though this is technically modelled as an lvalue-to-rvalue
101         // conversion, it calls a constructor and binds 'a' to a reference, so
102         // it results in an odr-use.
103         ellipsis(a); // expected-error {{enclosing function}}
104       }
105     };
106   }
107 
108 #if __cplusplus >= 201103L
volatile_lval()109   void volatile_lval() {
110     struct A { int n; };
111     constexpr A a = {0}; // expected-note {{here}}
112     struct B {
113       void f() {
114         // An lvalue-to-rvalue conversion of a volatile lvalue always results
115         // in odr-use.
116         int A::*p = &A::n;
117         int x = a.*p;
118         volatile int A::*q = p;
119         int y = a.*q; // expected-error {{enclosing function}}
120       }
121     };
122   }
123 #endif
124 
discarded_lval()125   void discarded_lval() {
126     struct A { int x; mutable int y; volatile int z; };
127     A a; // expected-note 1+{{here}}
128     int &r = a.x; // expected-note {{here}}
129     struct B {
130       void f() {
131         a.x; // expected-warning {{unused}}
132         a.*&A::x; // expected-warning {{unused}}
133         true ? a.x : a.y; // expected-warning {{unused}}
134         (void)a.x;
135         a.x, discarded_lval(); // expected-warning {{unused}}
136 #if 1 // FIXME: These errors are all incorrect; the above code is valid.
137       // expected-error@-6 {{enclosing function}}
138       // expected-error@-6 {{enclosing function}}
139       // expected-error@-6 2{{enclosing function}}
140       // expected-error@-6 {{enclosing function}}
141       // expected-error@-6 {{enclosing function}}
142 #endif
143 
144         // 'volatile' qualifier triggers an lvalue-to-rvalue conversion.
145         a.z; // expected-error {{enclosing function}}
146 #if __cplusplus < 201103L
147         // expected-warning@-2 {{assign into a variable}}
148 #endif
149 
150         // References always get "loaded" to determine what they reference,
151         // even if the result is discarded.
152         r; // expected-error {{enclosing function}} expected-warning {{unused}}
153       }
154     };
155   }
156 
157   namespace dr_example_1 {
158     extern int globx;
main()159     int main() {
160       const int &x = globx;
161       struct A {
162 #if __cplusplus < 201103L
163         // expected-error@+2 {{enclosing function}} expected-note@-3 {{here}}
164 #endif
165         const int *foo() { return &x; }
166       } a;
167       return *a.foo();
168     }
169   }
170 
171 #if __cplusplus >= 201103L
172   namespace dr_example_2 {
173     struct A {
174       int q;
Adr2083::dr_example_2::A175       constexpr A(int q) : q(q) {}
Adr2083::dr_example_2::A176       constexpr A(const A &a) : q(a.q * 2) {} // (note, not called)
177     };
178 
main(void)179     int main(void) {
180       constexpr A a(42);
181       constexpr int aq = a.q;
182       struct Q {
183         int foo() { return a.q; }
184       } q;
185       return q.foo();
186     }
187 
188     // Checking odr-use does not invent an lvalue-to-rvalue conversion (and
189     // hence copy construction) on the potential result variable.
190     struct B {
191       int b = 42;
Bdr2083::dr_example_2::B192       constexpr B() {}
193       constexpr B(const B&) = delete;
194     };
f()195     void f() {
196       constexpr B b;
197       struct Q {
198         constexpr int foo() const { return b.b; }
199       };
200       static_assert(Q().foo() == 42, "");
201     }
202   }
203 #endif
204 }
205 
206 namespace dr2094 { // dr2094: 5
207   struct A { int n; };
208   struct B { volatile int n; };
209   static_assert(__is_trivially_copyable(volatile int), "");
210   static_assert(__is_trivially_copyable(const volatile int), "");
211   static_assert(__is_trivially_copyable(const volatile int[]), "");
212   static_assert(__is_trivially_copyable(A), "");
213   static_assert(__is_trivially_copyable(volatile A), "");
214   static_assert(__is_trivially_copyable(const volatile A), "");
215   static_assert(__is_trivially_copyable(const volatile A[]), "");
216   static_assert(__is_trivially_copyable(B), "");
217 
218   static_assert(__is_trivially_constructible(A, A const&), "");
219   static_assert(__is_trivially_constructible(B, B const&), "");
220 
221   static_assert(__is_trivially_assignable(A, const A&), "");
222   static_assert(__is_trivially_assignable(B, const B&), "");
223 }
224