1 // RUN: %clang_cc1 -std=c++1z -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu
3 namespace BaseClassAggregateInit
{
6 constexpr A(int n
) : a(n
), b(3 * n
), c(b
- 1) {} // expected-note {{outside the range of representable}}
7 constexpr A() : A(10) {};
11 struct D
: B
, C
{ int k
; };
13 constexpr D d1
= { 1, 2, 3 };
14 static_assert(d1
.a
== 1 && d1
.b
== 3 && d1
.c
== 2 && d1
.q
== 2 && d1
.k
== 3);
16 constexpr D d2
= { 14 };
17 static_assert(d2
.a
== 14 && d2
.b
== 42 && d2
.c
== 41 && d2
.q
== 0 && d2
.k
== 0);
19 constexpr D d3
= { A(5), C
{2}, 1 };
20 static_assert(d3
.a
== 5 && d3
.b
== 15 && d3
.c
== 14 && d3
.q
== 2 && d3
.k
== 1);
23 static_assert(d4
.a
== 10 && d4
.b
== 30 && d4
.c
== 29 && d4
.q
== 0 && d4
.k
== 0);
25 constexpr D d5
= { __INT_MAX__
}; // expected-error {{must be initialized by a constant expression}}
26 // expected-note-re@-1 {{in call to 'A({{.*}})'}}
29 namespace NoexceptFunctionTypes
{
30 template<typename T
> constexpr bool f() noexcept(true) { return true; }
31 constexpr bool (*fp
)() = f
<int>;
32 static_assert(f
<int>());
35 template<typename T
> struct A
{
36 constexpr bool f() noexcept(true) { return true; }
37 constexpr bool g() { return f(); }
38 constexpr bool operator()() const noexcept(true) { return true; }
40 static_assert(A
<int>().f());
41 static_assert(A
<int>().g());
42 static_assert(A
<int>()());
45 namespace Cxx17CD_NB_GB19
{
51 template <class T
> struct S
{ static constexpr bool value
= true; };
52 template <class T
> constexpr bool f() { return true; }
53 template <class T
> constexpr bool v
= true;
56 if constexpr (true) {}
57 else if constexpr (f
<int>()) {}
58 else if constexpr (S
<int>::value
) {}
59 else if constexpr (v
<int>) {}
63 // Check that assignment operators evaluate their operands right-to-left.
65 template<typename T
> struct lvalue
{
67 constexpr T
&get() { return t
; }
72 constexpr UserDefined
&operator=(const UserDefined
&) { return *this; }
73 constexpr UserDefined
&operator+=(const UserDefined
&) { return *this; }
74 constexpr void operator<<(const UserDefined
&) const {}
75 constexpr void operator>>(const UserDefined
&) const {}
76 constexpr void operator+(const UserDefined
&) const {}
77 constexpr void operator[](int) const {}
79 constexpr UserDefined ud
;
82 constexpr void operator+=(NonMember
, NonMember
) {}
83 constexpr void operator<<(NonMember
, NonMember
) {}
84 constexpr void operator>>(NonMember
, NonMember
) {}
85 constexpr void operator+(NonMember
, NonMember
) {}
86 constexpr NonMember nm
;
88 constexpr void f(...) {}
90 // Helper to ensure that 'a' is evaluated before 'b'.
95 template <typename T
> constexpr T
&&a(T
&&v
) {
99 template <typename T
> constexpr T
&&b(T
&&v
) {
106 constexpr bool ok() { return done_a
&& done_b
; }
109 // SEQ(expr), where part of the expression is tagged A(...) and part is
110 // tagged B(...), checks that A is evaluated before B.
113 #define SEQ(...) static_assert([](seq_checker sc) { void(__VA_ARGS__); return sc.ok(); }({}))
115 // Longstanding sequencing rules.
117 SEQ((A(true) ? B(2) : throw "huh?"));
118 SEQ((A(false) ? throw "huh?" : B(2)));
119 SEQ(A(true) && B(true));
120 SEQ(A(false) || B(true));
124 // Rules 1 and 2 have no effect ('b' is not an expression).
127 SEQ(A(ud
).*B(&UserDefined::n
));
128 SEQ(A(&ud
)->*B(&UserDefined::n
));
130 // Rule 4: a(b1, b2, b3)
131 SEQ(A(f
)(B(1), B(2), B(3)));
133 // Rule 5: b = a, b @= a
134 SEQ(B(lvalue
<int>().get()) = A(0));
135 SEQ(B(lvalue
<UserDefined
>().get()) = A(ud
));
136 SEQ(B(lvalue
<int>().get()) += A(0));
137 SEQ(B(lvalue
<UserDefined
>().get()) += A(ud
));
138 SEQ(B(lvalue
<NonMember
>().get()) += A(nm
));
141 constexpr int arr
[3] = {};
158 // No particular order of evaluation is specified in other cases, but we in
159 // practice evaluate left-to-right.
160 // FIXME: Technically we're expected to check for undefined behavior due to
161 // unsequenced read and modification and treat it as non-constant due to UB.
172 namespace LambdaCallOp
{
173 constexpr void get_lambda(void (*&p
)()) { p
= []{}; }
174 constexpr void call_lambda() {
175 void (*p
)() = nullptr;
181 // This used to crash due to an assertion failure,
188 template <const C
*p
> void f() {
189 const auto &[c
] = *p
;
190 &c
; // expected-warning {{expression result unused}}