[Clang] replace 'bitfield' with 'bit-field' for consistency (#117881)
[llvm-project.git] / clang / test / SemaCXX / constant-expression-cxx2b.cpp
blob42b3f81cc713d10f1a763e3c428e838b8d4dbe2e
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}}
7 };
9 struct Constexpr{};
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}}
16 return m;
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}}
21 return m;
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}}
27 return m;
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}}
33 return m;
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}}
39 return &m - &m;
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}}
44 return &m - &m;
47 constexpr int j(int n) {
48 if (!n)
49 return 0;
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}}
51 return m;
53 constexpr int j0 = j(0);
55 constexpr int k(int n) {
56 if (!n)
57 return 0;
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}}
60 return m;
62 constexpr int k0 = k(0);
64 constexpr int j_evaluated(int n) {
65 if (!n)
66 return 0;
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}}
69 return m;
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) {
76 if (!n)
77 return 0;
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}}
81 return m;
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}}
90 return m;
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}}
96 return m;
99 constexpr int non_literal(bool b) {
100 if (!b)
101 return 0;
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) {
110 if (x) {
111 return 0;
112 } else {
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}}
116 test:
117 return 0;
120 int a = f(0);
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}}
128 return 0;
131 constexpr int d = label();
133 } // namespace eval_goto
135 #endif
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}}
142 return m;
145 auto b = [](int n) constexpr {
146 if (!n)
147 return 0;
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}}
149 return m;
151 (1);
153 auto c = [](int n) constexpr {
154 if (!n)
155 return 0;
156 else
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}}
159 test:
160 return 1;
162 c(0);
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 {
167 if (!b)
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}}
171 return 0;
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);
179 #endif
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
184 // C++20 rules).
185 int test_lambdas_implicitly_constexpr() {
187 auto b = [](int n) { // cxx2a-note 2{{declared here}}
188 if (!n)
189 return 0;
190 static const int m = n; // cxx23-note {{control flows through the definition of a static variable}}
191 return m;
194 auto b1 = b(1);
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}}
203 if (!n)
204 return 0;
205 else
206 goto test; // cxx23-note {{subexpression not valid in a constant expression}}
207 test:
208 return 1;
210 c(0);
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}}
219 if (b)
220 NonLiteral n; // cxx23-note {{non-constexpr constructor 'NonLiteral' cannot be used in a constant expression}}
221 return 0;
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}}
235 if (!b)
236 T t;
237 return 0;
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() {
247 struct Constexpr{
248 constexpr double f() const {
249 return 42;
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);