Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Clang][C++2b] P2242R3: Non-literal variables [...] in constexpr
Allow goto, labelled statements as well as `static`, `thread_local`, and non-literal variables in `constexpr` functions. As specified. for all of the above (except labelled statements) constant evaluation of the construct still fails. For `constexpr` bodies, the proposal is implemented with diagnostics as a language extension in older language modes. For determination of whether a lambda body satisfies the requirements for a constexpr function, the proposal is implemented only in C++2b mode to retain the semantics of older modes for programs conforming to them. Reviewed By: aaron.ballman, hubert.reinterpretcast, erichkeane Differential Revision: https://reviews.llvm.org/D111400
- Loading branch information
Showing
13 changed files
with
452 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// RUN: %clang_cc1 -verify -std=c++2b -Wpre-c++2b-compat %s | ||
|
||
constexpr int h(int n) { | ||
if (!n) | ||
return 0; | ||
static const int m = n; // expected-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}} | ||
return m; | ||
} | ||
|
||
constexpr int i(int n) { | ||
if (!n) | ||
return 0; | ||
thread_local const int m = n; // expected-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}} | ||
return m; | ||
} | ||
|
||
constexpr int g() { // expected-error {{constexpr function never produces a constant expression}} | ||
goto test; // expected-note {{subexpression not valid in a constant expression}} \ | ||
// expected-warning {{use of this statement in a constexpr function is incompatible with C++ standards before C++2b}} | ||
test: | ||
return 0; | ||
} | ||
|
||
constexpr void h() { | ||
label:; // expected-warning {{use of this statement in a constexpr function is incompatible with C++ standards before C++2b}} | ||
} | ||
|
||
struct NonLiteral { | ||
NonLiteral() {} | ||
}; | ||
|
||
constexpr void non_literal() { // expected-error {{constexpr function never produces a constant expression}} | ||
NonLiteral n; // expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} | ||
} | ||
|
||
constexpr void non_literal2(bool b) { | ||
if (!b) | ||
NonLiteral n; | ||
} | ||
|
||
constexpr int c_thread_local(int n) { | ||
if (!n) | ||
return 0; | ||
static _Thread_local int a; // expected-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}} | ||
_Thread_local int b; // // expected-error {{'_Thread_local' variables must have global storage}} | ||
return 0; | ||
} | ||
|
||
constexpr int gnu_thread_local(int n) { | ||
if (!n) | ||
return 0; | ||
static __thread int a; // expected-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}} | ||
__thread int b; // expected-error {{'__thread' variables must have global storage}} | ||
return 0; | ||
} |
Oops, something went wrong.