[clang-cl] Ignore /Wv and /Wv:17 flags
[llvm-project.git] / clang / test / SemaCXX / constant-expression-cxx2b.cpp
blob0657a35947ade60da502324a0ca4e542a458b5ad
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}}
5 NonLiteral() {}
6 };
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}}
13 return m;
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}}
18 return m;
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}}
24 return m;
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}}
30 return m;
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}}
36 return &m - &m;
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}}
41 return &m - &m;
44 constexpr int j(int n) {
45 if (!n)
46 return 0;
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}}
48 return m;
50 constexpr int j0 = j(0);
52 constexpr int k(int n) {
53 if (!n)
54 return 0;
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}}
57 return m;
59 constexpr int k0 = k(0);
61 constexpr int j_evaluated(int n) {
62 if (!n)
63 return 0;
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}}
66 return m;
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) {
73 if (!n)
74 return 0;
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}}
78 return m;
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}}
87 return m;
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}}
93 return m;
96 constexpr int non_literal(bool b) {
97 if (!b)
98 return 0;
99 NonLiteral n;
102 constexpr int non_literal_1 = non_literal(false);
104 namespace eval_goto {
106 constexpr int f(int x) {
107 if (x) {
108 return 0;
109 } else {
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}}
113 test:
114 return 0;
117 int a = f(0);
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}}
125 return 0;
128 constexpr int d = label();
130 } // namespace eval_goto
132 #endif
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}}
140 return m;
143 auto b = [](int n) constexpr {
144 if (!n)
145 return 0;
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}}
147 return m;
149 (1);
151 auto c = [](int n) constexpr {
152 if (!n)
153 return 0;
154 else
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}}
157 test:
158 return 1;
160 c(0);
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 {
165 if (!b)
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}}
168 return 0;
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);
176 #endif
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
181 // C++20 rules).
182 int test_lambdas_implicitly_constexpr() {
184 auto b = [](int n) { // cxx2a-note 2{{declared here}}
185 if (!n)
186 return 0;
187 static const int m = n; // cxx2b-note {{control flows through the definition of a static variable}}
188 return m;
191 auto b1 = b(1);
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}}
200 if (!n)
201 return 0;
202 else
203 goto test; // cxx2b-note {{subexpression not valid in a constant expression}}
204 test:
205 return 1;
207 c(0);
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}}
216 if (b)
217 NonLiteral n; // cxx2b-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}}
218 return 0;
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}}
232 if (!b)
233 T t;
234 return 0;
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}}