1 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,cxx2a %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wno-c++2b-extensions
2 // RUN: %clang_cc1 -std=c++2b -fsyntax-only -verify=expected,cxx2b %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wpre-c++2b-compat
4 struct NonLiteral
{ // cxx2a-note {{'NonLiteral' is not literal}}
8 #if __cplusplus > 202002L
10 constexpr int f(int n
) { // expected-error {{constexpr function never produces a constant expression}}
11 static const int m
= n
; // expected-note {{control flows through the definition of a static variable}} \
12 // cxx2b-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}}
15 constexpr int g(int n
) { // expected-error {{constexpr function never produces a constant expression}}
16 thread_local
const int m
= n
; // expected-note {{control flows through the definition of a thread_local variable}} \
17 // cxx2b-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}}
21 constexpr int c_thread_local(int n
) { // expected-error {{constexpr function never produces a constant expression}}
22 static _Thread_local
int m
= 0; // expected-note {{control flows through the definition of a thread_local variable}} \
23 // cxx2b-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}}
27 constexpr int gnu_thread_local(int n
) { // expected-error {{constexpr function never produces a constant expression}}
28 static __thread
int m
= 0; // expected-note {{control flows through the definition of a thread_local variable}} \
29 // cxx2b-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}}
33 constexpr int h(int n
) { // expected-error {{constexpr function never produces a constant expression}}
34 static const int m
= n
; // expected-note {{control flows through the definition of a static variable}} \
35 // cxx2b-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}}
38 constexpr int i(int n
) { // expected-error {{constexpr function never produces a constant expression}}
39 thread_local
const int m
= n
; // expected-note {{control flows through the definition of a thread_local variable}} \
40 // cxx2b-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}}
44 constexpr int j(int n
) {
47 static const int m
= n
; // cxx2b-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}}
50 constexpr int j0
= j(0);
52 constexpr int k(int n
) {
55 thread_local
const int m
= n
; // cxx2b-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}}
59 constexpr int k0
= k(0);
61 constexpr int j_evaluated(int n
) {
64 static const int m
= n
; // expected-note {{control flows through the definition of a static variable}} \
65 // cxx2b-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}}
69 constexpr int je
= j_evaluated(1); // expected-error {{constexpr variable 'je' must be initialized by a constant expression}} \
70 // expected-note {{in call}}
72 constexpr int k_evaluated(int n
) {
75 thread_local
const int m
= n
; // expected-note {{control flows through the definition of a thread_local variable}} \
76 // cxx2b-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}}
81 constexpr int ke
= k_evaluated(1); // expected-error {{constexpr variable 'ke' must be initialized by a constant expression}} \
82 // expected-note {{in call}}
84 constexpr int static_constexpr() { // expected-error {{constexpr function never produces a constant expression}}
85 static constexpr int m
= 42; // expected-note {{control flows through the definition of a static variable}} \
86 // cxx2b-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}}
90 constexpr int thread_local_constexpr() { // expected-error {{constexpr function never produces a constant expression}}
91 thread_local
constexpr int m
= 42; // expected-note {{control flows through the definition of a thread_local variable}} \
92 // cxx2b-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}}
96 constexpr int non_literal(bool b
) {
102 constexpr int non_literal_1
= non_literal(false);
104 namespace eval_goto
{
106 constexpr int f(int x
) {
110 goto test
; // expected-note {{subexpression not valid in a constant expression}} \
111 // cxx2b-warning {{use of this statement in a constexpr function is incompatible with C++ standards before C++2b}}
118 constexpr int b
= f(0); // expected-error {{must be initialized by a constant expression}} \
119 // expected-note {{in call to 'f(0)'}}
120 constexpr int c
= f(1);
122 constexpr int label() {
124 test
: // cxx2b-warning {{use of this statement in a constexpr function is incompatible with C++ standards before C++2b}}
128 constexpr int d
= label();
130 } // namespace eval_goto
134 // Test that explicitly constexpr lambdas behave correctly,
135 // This is to be contrasted with the test for implicitly constexpr lambdas below.
136 int test_in_lambdas() {
137 auto a
= []() constexpr { // expected-error{{constexpr function never produces a constant expression}}
138 static const int m
= 32; // expected-note {{control flows through the definition of a static variable}} \
139 // cxx2b-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}}
143 auto b
= [](int n
) constexpr {
146 static const int m
= n
; // cxx2b-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}}
151 auto c
= [](int n
) constexpr {
155 goto test
; // expected-note {{subexpression not valid in a constant expression}} \
156 // cxx2b-warning {{use of this statement in a constexpr function is incompatible with C++ standards before C++2b}}
161 constexpr auto c_error
= c(1); // expected-error {{constexpr variable 'c_error' must be initialized by a constant expression}} \
162 // expected-note {{in call to}}
164 auto non_literal
= [](bool b
) constexpr {
166 NonLiteral n
; // cxx2b-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \
167 // cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}}
171 #if __cplusplus > 202002L
172 constexpr auto non_literal_ko
= non_literal(false); // cxx2b-error {{constexpr variable 'non_literal_ko' must be initialized by a constant expression}} \
173 // cxx2b-note {{in call}}
175 constexpr auto non_literal_ok
= non_literal(true);
179 // Test whether lambdas are correctly treated as implicitly constexpr under the
180 // relaxed C++23 rules (and similarly as not implicitly constexpr under the
182 int test_lambdas_implicitly_constexpr() {
184 auto b
= [](int n
) { // cxx2a-note 2{{declared here}}
187 static const int m
= n
; // cxx2b-note {{control flows through the definition of a static variable}}
192 constexpr auto b2
= b(0); // cxx2a-error {{must be initialized by a constant expression}} \
193 // cxx2a-note {{non-constexpr function}}
195 constexpr auto b3
= b(1); // expected-error{{constexpr variable 'b3' must be initialized by a constant expression}} \
196 // cxx2a-note {{non-constexpr function}} \
197 // cxx2b-note {{in call}}
199 auto c
= [](int n
) { // cxx2a-note 2{{declared here}}
203 goto test
; // cxx2b-note {{subexpression not valid in a constant expression}}
208 constexpr auto c_ok
= c(0); // cxx2a-error {{must be initialized by a constant expression}} \
209 // cxx2a-note {{non-constexpr function}}
211 constexpr auto c_error
= c(1); // expected-error {{constexpr variable 'c_error' must be initialized by a constant expression}} \
212 // cxx2a-note {{non-constexpr function}} \
213 // cxx2b-note {{in call to}}
215 auto non_literal
= [](bool b
) { // cxx2a-note 2{{declared here}}
217 NonLiteral n
; // cxx2b-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}}
221 constexpr auto non_literal_ko
= non_literal(true); // expected-error {{constexpr variable 'non_literal_ko' must be initialized by a constant expression}} \
222 // cxx2a-note {{non-constexpr function}} \
223 // cxx2b-note {{in call}}
225 constexpr auto non_literal_ok
= non_literal(false); // cxx2a-error {{must be initialized by a constant expression}} \
226 // cxx2a-note {{non-constexpr function}}
229 template <typename T
>
230 constexpr auto dependent_var_def_lambda(void) {
231 return [](bool b
) { // cxx2a-note {{declared here}}
238 constexpr auto non_literal_valid_in_cxx2b
= dependent_var_def_lambda
<NonLiteral
>()(true); // \
239 // cxx2a-error {{constexpr variable 'non_literal_valid_in_cxx2b' must be initialized by a constant expression}} \
240 // cxx2a-note {{non-constexpr function}}