-
Notifications
You must be signed in to change notification settings - Fork 14.6k
Closed as not planned
Labels
clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"duplicateResolved as duplicateResolved as duplicaterejects-valid
Description
While investigating a potential GCC bug, I went through https://eel.is/c++draft/expr.const#9 which contains the following (reduced) example:
struct Swim {
constexpr int phelps() { return 28; }
};
void splash(Swim& swam) {
static_assert(swam.phelps() == 28); // OK
}
clang trunk rejects this with:
<source>:6:17: error: static assertion expression is not an integral constant expression
6 | static_assert(swam.phelps() == 28); // OK
| ^~~~~~~~~~~~~~~~~~~
<source>:6:17: note: function parameter 'swam' with unknown value cannot be used in a constant expression
<source>:5:19: note: declared here
5 | void splash(Swim& swam) {
| ^
Whereas GCC accepts it. https://godbolt.org/z/s1vTK7G3h
--
Moreover, if one feeds the whole example to clang (replacing size_t
with int
and removing the lines that are specified to be invalid):
template <typename T, int N>
constexpr int array_size(T (&)[N]) {
return N;
}
void use_array(int const (&gold_medal_mel)[2]) {
constexpr auto gold = array_size(gold_medal_mel); // OK
}
constexpr auto olympic_mile() {
const int ledecky = 1500;
return []{ return ledecky; };
}
static_assert(olympic_mile()() == 1500); // OK
struct Swim {
constexpr int phelps() { return 28; }
virtual constexpr int lochte() { return 12; }
int coughlin = 12;
};
constexpr int how_many(Swim& swam) {
Swim* p = &swam;
return (p + 1 - 1)->phelps();
}
void splash(Swim& swam) {
static_assert(swam.phelps() == 28); // OK
static_assert((&swam)->phelps() == 28); // OK
Swim* pswam = &swam;
static_assert(how_many(swam) == 28); // OK
static_assert(Swim().lochte() == 12); // OK
}
clang trunk rejects with:
<source>:7:18: error: constexpr variable 'gold' must be initialized by a constant expression
7 | constexpr auto gold = array_size(gold_medal_mel); // OK
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:7:36: note: function parameter 'gold_medal_mel' with unknown value cannot be used in a constant expression
7 | constexpr auto gold = array_size(gold_medal_mel); // OK
| ^
<source>:6:28: note: declared here
6 | void use_array(int const (&gold_medal_mel)[2]) {
| ^
<source>:28:17: error: static assertion expression is not an integral constant expression
28 | static_assert(swam.phelps() == 28); // OK
| ^~~~~~~~~~~~~~~~~~~
<source>:28:17: note: function parameter 'swam' with unknown value cannot be used in a constant expression
<source>:27:19: note: declared here
27 | void splash(Swim& swam) {
| ^
<source>:29:17: error: static assertion expression is not an integral constant expression
29 | static_assert((&swam)->phelps() == 28); // OK
| ^~~~~~~~~~~~~~~~~~~~~~~
<source>:29:19: note: function parameter 'swam' with unknown value cannot be used in a constant expression
29 | static_assert((&swam)->phelps() == 28); // OK
| ^
<source>:27:19: note: declared here
27 | void splash(Swim& swam) {
| ^
<source>:33:17: error: static assertion expression is not an integral constant expression
33 | static_assert(how_many(swam) == 28); // OK
| ^~~~~~~~~~~~~~~~~~~~
<source>:33:26: note: function parameter 'swam' with unknown value cannot be used in a constant expression
33 | static_assert(how_many(swam) == 28); // OK
| ^
<source>:27:19: note: declared here
27 | void splash(Swim& swam) {
| ^
4 errors generated.
Compiler returned: 1
Whereas GCC accepts. https://godbolt.org/z/3r9nKc9bz
This seems to be related to #63139
Metadata
Metadata
Assignees
Labels
clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"duplicateResolved as duplicateResolved as duplicaterejects-valid