1 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,cxx2a %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wno-c++23-extensions
2 // RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify=expected,cxx23 %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wpre-c++23-compat
4 struct NonLiteral
{ // cxx2a-note {{'NonLiteral' is not literal}} \
5 // cxx23-note 2{{'NonLiteral' is not literal}}
6 NonLiteral() {} // cxx23-note 2{{declared here}}
11 #if __cplusplus > 202002L
13 constexpr int f(int n
) { // cxx2a-error {{constexpr function never produces a constant expression}}
14 static const int m
= n
; // cxx2a-note {{control flows through the definition of a static variable}} \
15 // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}
18 constexpr int g(int n
) { // cxx2a-error {{constexpr function never produces a constant expression}}
19 thread_local
const int m
= n
; // cxx2a-note {{control flows through the definition of a thread_local variable}} \
20 // cxx23-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++23}}
24 constexpr int c_thread_local(int n
) { // cxx2a-error {{constexpr function never produces a constant expression}}
25 static _Thread_local
int m
= 0; // cxx2a-note {{control flows through the definition of a thread_local variable}} \
26 // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}
30 constexpr int gnu_thread_local(int n
) { // cxx2a-error {{constexpr function never produces a constant expression}}
31 static __thread
int m
= 0; // cxx2a-note {{control flows through the definition of a thread_local variable}} \
32 // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}
36 constexpr int h(int n
) { // cxx2a-error {{constexpr function never produces a constant expression}}
37 static const int m
= n
; // cxx2a-note {{control flows through the definition of a static variable}} \
38 // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}
41 constexpr int i(int n
) { // cxx2a-error {{constexpr function never produces a constant expression}}
42 thread_local
const int m
= n
; // cxx2a-note {{control flows through the definition of a thread_local variable}} \
43 // cxx23-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++23}}
47 constexpr int j(int n
) {
50 static const int m
= n
; // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}
53 constexpr int j0
= j(0);
55 constexpr int k(int n
) {
58 thread_local
const int m
= n
; // cxx23-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++23}}
62 constexpr int k0
= k(0);
64 constexpr int j_evaluated(int n
) {
67 static const int m
= n
; // expected-note {{control flows through the definition of a static variable}} \
68 // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}
72 constexpr int je
= j_evaluated(1); // expected-error {{constexpr variable 'je' must be initialized by a constant expression}} \
73 // expected-note {{in call}}
75 constexpr int k_evaluated(int n
) {
78 thread_local
const int m
= n
; // expected-note {{control flows through the definition of a thread_local variable}} \
79 // cxx23-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++23}}
84 constexpr int ke
= k_evaluated(1); // expected-error {{constexpr variable 'ke' must be initialized by a constant expression}} \
85 // expected-note {{in call}}
87 constexpr int static_constexpr() {
88 static constexpr int m
= 42; // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}
89 static constexpr Constexpr foo
; // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}
93 constexpr int thread_local_constexpr() {
94 thread_local
constexpr int m
= 42; // cxx23-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++23}}
95 thread_local
constexpr Constexpr foo
; // cxx23-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++23}}
99 constexpr int non_literal(bool b
) {
102 NonLiteral n
; // cxx23-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++23}}
105 constexpr int non_literal_1
= non_literal(false);
107 namespace eval_goto
{
109 constexpr int f(int x
) {
113 goto test
; // expected-note {{subexpression not valid in a constant expression}} \
114 // cxx23-warning {{use of this statement in a constexpr function is incompatible with C++ standards before C++23}}
121 constexpr int b
= f(0); // expected-error {{must be initialized by a constant expression}} \
122 // expected-note {{in call to 'f(0)'}}
123 constexpr int c
= f(1);
125 constexpr int label() {
127 test
: // cxx23-warning {{use of this statement in a constexpr function is incompatible with C++ standards before C++23}}
131 constexpr int d
= label();
133 } // namespace eval_goto
137 // Test that explicitly constexpr lambdas behave correctly,
138 // This is to be contrasted with the test for implicitly constexpr lambdas below.
139 int test_in_lambdas() {
140 auto a
= []() constexpr {
141 static const int m
= 32; // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}
145 auto b
= [](int n
) constexpr {
148 static const int m
= n
; // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}
153 auto c
= [](int n
) constexpr {
157 goto test
; // expected-note {{subexpression not valid in a constant expression}} \
158 // cxx23-warning {{use of this statement in a constexpr function is incompatible with C++ standards before C++23}}
163 constexpr auto c_error
= c(1); // expected-error {{constexpr variable 'c_error' must be initialized by a constant expression}} \
164 // expected-note {{in call to}}
166 auto non_literal
= [](bool b
) constexpr {
168 NonLiteral n
; // cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++23}} \
169 // cxx23-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++23}} \
170 // cxx23-note {{non-constexpr constructor 'NonLiteral' cannot be used in a constant expression}}
174 #if __cplusplus > 202002L
175 constexpr auto non_literal_ko
= non_literal(false); // cxx23-error {{constexpr variable 'non_literal_ko' must be initialized by a constant expression}} \
176 // cxx23-note {{in call}}
178 constexpr auto non_literal_ok
= non_literal(true);
182 // Test whether lambdas are correctly treated as implicitly constexpr under the
183 // relaxed C++23 rules (and similarly as not implicitly constexpr under the
185 int test_lambdas_implicitly_constexpr() {
187 auto b
= [](int n
) { // cxx2a-note 2{{declared here}}
190 static const int m
= n
; // cxx23-note {{control flows through the definition of a static variable}}
195 constexpr auto b2
= b(0); // cxx2a-error {{must be initialized by a constant expression}} \
196 // cxx2a-note {{non-constexpr function}}
198 constexpr auto b3
= b(1); // expected-error{{constexpr variable 'b3' must be initialized by a constant expression}} \
199 // cxx2a-note {{non-constexpr function}} \
200 // cxx23-note {{in call}}
202 auto c
= [](int n
) { // cxx2a-note 2{{declared here}}
206 goto test
; // cxx23-note {{subexpression not valid in a constant expression}}
211 constexpr auto c_ok
= c(0); // cxx2a-error {{must be initialized by a constant expression}} \
212 // cxx2a-note {{non-constexpr function}}
214 constexpr auto c_error
= c(1); // expected-error {{constexpr variable 'c_error' must be initialized by a constant expression}} \
215 // cxx2a-note {{non-constexpr function}} \
216 // cxx23-note {{in call to}}
218 auto non_literal
= [](bool b
) { // cxx2a-note 2{{declared here}}
220 NonLiteral n
; // cxx23-note {{non-constexpr constructor 'NonLiteral' cannot be used in a constant expression}}
224 constexpr auto non_literal_ko
= non_literal(true); // expected-error {{constexpr variable 'non_literal_ko' must be initialized by a constant expression}} \
225 // cxx2a-note {{non-constexpr function}} \
226 // cxx23-note {{in call}}
228 constexpr auto non_literal_ok
= non_literal(false); // cxx2a-error {{must be initialized by a constant expression}} \
229 // cxx2a-note {{non-constexpr function}}
232 template <typename T
>
233 constexpr auto dependent_var_def_lambda() {
234 return [](bool b
) { // cxx2a-note {{declared here}}
241 constexpr auto non_literal_valid_in_cxx23
= dependent_var_def_lambda
<NonLiteral
>()(true); // \
242 // cxx2a-error {{constexpr variable 'non_literal_valid_in_cxx23' must be initialized by a constant expression}} \
243 // cxx2a-note {{non-constexpr function}}
246 constexpr double evaluate_static_constexpr() {
248 constexpr double f() const {
252 thread_local
constexpr Constexpr t
; // cxx23-warning {{before C++23}}
253 static constexpr Constexpr s
; // cxx23-warning {{before C++23}}
254 return t
.f() + s
.f();
256 static_assert(evaluate_static_constexpr() == 84);