- Support label at end of compound statement (`P2324 <https://wg21.link/p2324r2>`_).
- Implemented `P1169R4: static operator() <https://wg21.link/P1169R4>`_.
- Implemented "char8_t Compatibility and Portability Fix" (`P2513R3 <https://wg21.link/P2513R3>`_).
- This Change was applied to C++20 as a Defect Report.
+ This change was applied to C++20 as a Defect Report.
+- Implemented "Permitting static constexpr variables in constexpr functions" (`P2647R1 <https://wg21.link/P2647R1>_`).
CUDA/HIP Language Changes in Clang
----------------------------------
static bool CheckLocalVariableDeclaration(EvalInfo &Info, const VarDecl *VD) {
// An expression E is a core constant expression unless the evaluation of E
// would evaluate one of the following: [C++2b] - a control flow that passes
- // through a declaration of a variable with static or thread storage duration.
- if (VD->isLocalVarDecl() && VD->isStaticLocal()) {
+ // through a declaration of a variable with static or thread storage duration
+ // unless that variable is usable in constant expressions.
+ if (VD->isLocalVarDecl() && VD->isStaticLocal() &&
+ !VD->isUsableInConstantExpressions(Info.Ctx)) {
Info.CCEDiag(VD->getLocation(), diag::note_constexpr_static_local)
<< (VD->getTSCSpec() == TSCS_unspecified ? 0 : 1) << VD;
return false;
Builder.defineMacro("__cpp_unicode_literals", "200710L");
Builder.defineMacro("__cpp_user_defined_literals", "200809L");
Builder.defineMacro("__cpp_lambdas", "200907L");
- Builder.defineMacro("__cpp_constexpr", LangOpts.CPlusPlus2b ? "202110L"
+ Builder.defineMacro("__cpp_constexpr", LangOpts.CPlusPlus2b ? "202211L"
: LangOpts.CPlusPlus20 ? "201907L"
: LangOpts.CPlusPlus17 ? "201603L"
: LangOpts.CPlusPlus14 ? "201304L"
#error "wrong value for __cpp_lambdas"
#endif
-#if check(constexpr, 0, 200704, 201304, 201603, 201907, 202110)
+#if check(constexpr, 0, 200704, 201304, 201603, 201907, 202211)
#error "wrong value for __cpp_constexpr"
#endif
NonLiteral() {}
};
+struct Constexpr{};
+
#if __cplusplus > 202002L
constexpr int f(int n) { // expected-error {{constexpr function never produces a constant expression}}
constexpr int ke = k_evaluated(1); // expected-error {{constexpr variable 'ke' must be initialized by a constant expression}} \
// expected-note {{in call}}
-constexpr int static_constexpr() { // expected-error {{constexpr function never produces a constant expression}}
- static constexpr int m = 42; // expected-note {{control flows through the definition of a static variable}} \
- // cxx2b-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}}
+constexpr int static_constexpr() {
+ static constexpr int m = 42; // cxx2b-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}}
+ static constexpr Constexpr foo; // cxx2b-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}}
return m;
}
-constexpr int thread_local_constexpr() { // expected-error {{constexpr function never produces a constant expression}}
- thread_local constexpr int m = 42; // expected-note {{control flows through the definition of a thread_local variable}} \
- // cxx2b-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}}
+constexpr int thread_local_constexpr() {
+ thread_local constexpr int m = 42; // cxx2b-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}}
+ thread_local constexpr Constexpr foo; // cxx2b-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}}
return m;
}
// Test that explicitly constexpr lambdas behave correctly,
// This is to be contrasted with the test for implicitly constexpr lambdas below.
int test_in_lambdas() {
- auto a = []() constexpr { // expected-error{{constexpr function never produces a constant expression}}
- static const int m = 32; // expected-note {{control flows through the definition of a static variable}} \
- // cxx2b-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}}
+ auto a = []() constexpr {
+ static const int m = 32; // cxx2b-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}}
return m;
};
constexpr auto non_literal_valid_in_cxx2b = dependent_var_def_lambda<NonLiteral>()(true); // \
// cxx2a-error {{constexpr variable 'non_literal_valid_in_cxx2b' must be initialized by a constant expression}} \
// cxx2a-note {{non-constexpr function}}
+
+
+constexpr double evaluate_static_constexpr() {
+ struct Constexpr{
+ constexpr double f() const {
+ return 42;
+ }
+ };
+ thread_local constexpr Constexpr t; // cxx2b-warning {{before C++2b}}
+ static constexpr Constexpr s; // cxx2b-warning {{before C++2b}}
+ return t.f() + s.f();
+}
+static_assert(evaluate_static_constexpr() == 84);
<tr>
<td>Permitting static constexpr variables in constexpr functions (DR)</td>
<td><a href="https://wg21.link/P2647R1">P2647R1</a></td>
- <td class="none" align="center">No</td>
+ <td class="unreleased" align="center">Clang 16</td>
</tr>
<tr>
<td>consteval needs to propagate up (DR)</td>