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++20 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
7 // RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
9 #if __cplusplus < 201103L
10 #define static_assert(...) _Static_assert(__VA_ARGS__)
13 namespace dr2007
{ // dr2007: 3.4
14 template<typename T
> struct A
{ typename
T::error e
; };
15 template<typename T
> struct B
{ };
18 int a
= b2
[0]; // expected-error {{does not provide a subscript operator}}
19 int b
= __builtin_addressof(b2
)->foo
; // expected-error {{no member}}
24 namespace dr2026
{ // dr2026: 11
25 template<int> struct X
{};
27 const int a
= a
+ 1; // expected-warning {{uninitialized}} expected-note {{here}} expected-note 0-1{{outside its lifetime}}
28 X
<a
> xa
; // expected-error {{constant expression}} expected-note {{initializer of 'a'}}
30 #if __cplusplus >= 201103L
31 constexpr int b
= b
; // expected-error {{constant expression}} expected-note {{outside its lifetime}}
32 [[clang::require_constant_initialization
]] int c
= c
; // expected-error {{constant initializer}} expected-note {{attribute}}
33 #if __cplusplus == 201103L
34 // expected-note@-2 {{read of non-const variable}} expected-note@-2 {{declared here}}
36 // expected-note@-4 {{outside its lifetime}}
40 #if __cplusplus > 201703L
41 constinit
int d
= d
; // expected-error {{constant initializer}} expected-note {{outside its lifetime}} expected-note {{'constinit'}}
45 static const int e
= e
+ 1; // expected-warning {{suspicious}} expected-note {{here}} expected-note 0-1{{outside its lifetime}}
46 X
<e
> xe
; // expected-error {{constant expression}} expected-note {{initializer of 'e'}}
48 #if __cplusplus >= 201103L
49 static constexpr int f
= f
; // expected-error {{constant expression}} expected-note {{outside its lifetime}}
50 [[clang::require_constant_initialization
]] static int g
= g
; // expected-error {{constant initializer}} expected-note {{attribute}}
51 #if __cplusplus == 201103L
52 // expected-note@-2 {{read of non-const variable}} expected-note@-2 {{declared here}}
54 // expected-note@-4 {{outside its lifetime}}
58 #if __cplusplus > 201703L
59 static constinit
int h
= h
; // expected-error {{constant initializer}} expected-note {{outside its lifetime}} expected-note {{'constinit'}}
64 namespace dr2061
{ // dr2061: yes
65 #if __cplusplus >= 201103L
69 // 'f' is the example from the DR. 'S' is an example where if we didn't
70 // properly handle the two being the same, we would get an incomplete
71 // type error during attempted instantiation.
72 template<typename T
> void f();
73 template<typename T
> struct S
;
80 template<> void f
<int>() { }
81 template<> struct S
<int> { };
92 namespace dr2076
{ // dr2076: 13
93 #if __cplusplus >= 201103L
94 namespace std_example
{
99 struct Params
{ int a
; int b
; };
107 string_view(int); // not an aggregate
110 string(int); // not an aggregate
111 operator string_view() const;
114 void foo(const string
&); // expected-note {{cannot convert initializer list}}
115 void bar(string_view
); // expected-note 2{{cannot convert initializer list}}
117 void func(const string
&arg
) {
118 // An argument in one set of braces is subject to user-defined conversions;
119 // an argument in two sets of braces is not, but an identity conversion is
124 foo({{{arg
}}}); // expected-error {{no matching function}}
127 bar({{arg
}}); // expected-error {{no matching function}}
128 bar({{{arg
}}}); // expected-error {{no matching function}}
133 namespace dr2082
{ // dr2082: 11
134 void test1(int x
, int = sizeof(x
)); // ok
135 #if __cplusplus >= 201103L
136 void test2(int x
, int = decltype(x
){}); // ok
140 namespace dr2083
{ // dr2083: partial
141 #if __cplusplus >= 201103L
142 void non_const_mem_ptr() {
147 constexpr A a
= {1, 2};
150 constexpr int g() const {
151 // OK, not an odr-use of 'a'.
155 static_assert(B
{&A::x
}.g() == 1, "");
156 static_assert(B
{&A::y
}.g() == 2, "");
162 // Note, references only get special odr-use / constant initializxer
163 // treatment in C++11 onwards. We continue to apply that even after DR2083.
164 void ref_to_non_const() {
166 const int &ra
= a
; // expected-note 0-1{{here}}
167 int &rb
= b
; // expected-note 0-1{{here}}
168 int &rc
= c
; // expected-note {{here}}
173 #if __cplusplus < 201103L
174 // expected-error@-3 {{in enclosing function}}
175 // expected-error@-3 {{in enclosing function}}
177 int c
= rc
; // expected-error {{in enclosing function}}
183 #if __cplusplus >= 201103L
184 struct NoMut1
{ int a
, b
; };
185 struct NoMut2
{ NoMut1 m
; };
186 struct NoMut3
: NoMut1
{
187 constexpr NoMut3(int a
, int b
) : NoMut1
{a
, b
} {}
193 struct Mut2
{ Mut1 m
; };
195 constexpr Mut3(int a
, int b
) : Mut1
{a
, b
} {}
197 void mutable_subobjects() {
198 constexpr NoMut1 nm1
= {1, 2};
199 constexpr NoMut2 nm2
= {1, 2};
200 constexpr NoMut3 nm3
= {1, 2};
201 constexpr Mut1 m1
= {1, 2}; // expected-note {{declared here}}
202 constexpr Mut2 m2
= {1, 2}; // expected-note {{declared here}}
203 constexpr Mut3 m3
= {1, 2}; // expected-note {{declared here}}
206 static_assert(nm1
.a
== 1, "");
207 static_assert(nm2
.m
.a
== 1, "");
208 static_assert(nm3
.a
== 1, "");
209 // Can't even access a non-mutable member of a variable containing mutable fields.
210 static_assert(m1
.a
== 1, ""); // expected-error {{enclosing function}}
211 static_assert(m2
.m
.a
== 1, ""); // expected-error {{enclosing function}}
212 static_assert(m3
.a
== 1, ""); // expected-error {{enclosing function}}
222 #if __cplusplus >= 201103L
225 A a
= {}; // expected-note {{here}}
229 // Even though this is technically modelled as an lvalue-to-rvalue
230 // conversion, it calls a constructor and binds 'a' to a reference, so
231 // it results in an odr-use.
232 ellipsis(a
); // expected-error {{enclosing function}}
237 #if __cplusplus >= 201103L
238 void volatile_lval() {
240 constexpr A a
= {0}; // expected-note {{here}}
243 // An lvalue-to-rvalue conversion of a volatile lvalue always results
247 volatile int A::*q
= p
;
248 int y
= a
.*q
; // expected-error {{enclosing function}}
254 void discarded_lval() {
255 struct A
{ int x
; mutable int y
; volatile int z
; };
256 A a
; // expected-note 1+{{here}}
257 int &r
= a
.x
; // expected-note {{here}}
260 a
.x
; // expected-warning {{unused}}
261 a
.*&A::x
; // expected-warning {{unused}}
262 true ? a
.x
: a
.y
; // expected-warning {{unused}}
264 a
.x
, discarded_lval(); // expected-warning {{left operand of comma operator has no effect}}
265 #if 1 // FIXME: These errors are all incorrect; the above code is valid.
266 // expected-error@-6 {{enclosing function}}
267 // expected-error@-6 {{enclosing function}}
268 // expected-error@-6 2{{enclosing function}}
269 // expected-error@-6 {{enclosing function}}
270 // expected-error@-6 {{enclosing function}}
273 // 'volatile' qualifier triggers an lvalue-to-rvalue conversion.
274 a
.z
; // expected-error {{enclosing function}}
275 #if __cplusplus < 201103L
276 // expected-warning@-2 {{assign into a variable}}
279 // References always get "loaded" to determine what they reference,
280 // even if the result is discarded.
281 r
; // expected-error {{enclosing function}} expected-warning {{unused}}
286 namespace dr_example_1
{
289 const int &x
= globx
;
291 #if __cplusplus < 201103L
292 // expected-error@+2 {{enclosing function}} expected-note@-3 {{here}}
294 const int *foo() { return &x
; }
300 #if __cplusplus >= 201103L
301 namespace dr_example_2
{
304 constexpr A(int q
) : q(q
) {}
305 constexpr A(const A
&a
) : q(a
.q
* 2) {} // (note, not called)
310 constexpr int aq
= a
.q
;
312 int foo() { return a
.q
; }
317 // Checking odr-use does not invent an lvalue-to-rvalue conversion (and
318 // hence copy construction) on the potential result variable.
322 constexpr B(const B
&) = delete;
327 constexpr int foo() const { return b
.b
; }
329 static_assert(Q().foo() == 42, "");
335 namespace dr2094
{ // dr2094: 5
337 struct B
{ volatile int n
; };
338 static_assert(__is_trivially_copyable(volatile int), "");
339 static_assert(__is_trivially_copyable(const volatile int), "");
340 static_assert(__is_trivially_copyable(const volatile int[]), "");
341 static_assert(__is_trivially_copyable(A
), "");
342 static_assert(__is_trivially_copyable(volatile A
), "");
343 static_assert(__is_trivially_copyable(const volatile A
), "");
344 static_assert(__is_trivially_copyable(const volatile A
[]), "");
345 static_assert(__is_trivially_copyable(B
), "");
347 static_assert(__is_trivially_constructible(A
, A
const&), "");
348 static_assert(__is_trivially_constructible(B
, B
const&), "");
350 static_assert(__is_trivially_assignable(A
, const A
&), "");
351 static_assert(__is_trivially_assignable(B
, const B
&), "");