Skip to content

Commit ee2c076

Browse files
Default-initialized local static constexpr in constant evaluation [GH #399]
The interpretation of the initialization statement of a local variable with static or thread storage duration (which, in a constant evaluation, must be usable in constant expressions) no longer allocates and initializes interpreter storage for it: its value is obtained when it is referenced. Previously, a default-initialized local "static constexpr" variable of class type caused the constant evaluation to fail.
1 parent f51894d commit ee2c076

4 files changed

Lines changed: 44 additions & 0 deletions

File tree

‎src/interpret.c‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9500,6 +9500,13 @@ loop body push a work item for it and continue in a later phase.
95009500
{ a_dynamic_init_ptr dip = stmt->variant.dynamic_init;
95019501
a_variable_ptr vp = dip->variable;
95029502
a_byte *var_storage;
9503+
if (var_has_static_or_thread_storage_duration(vp)) {
9504+
/* A local static variable (e.g., a default-initialized one of
9505+
class type) that is usable in constant expressions (see
9506+
stmk_decl below): its value is obtained when it is
9507+
referenced. */
9508+
break;
9509+
} /* if */
95039510
/* Allocate and bind storage for the variable. */
95049511
var_storage = do_constexpr_alloc_variable(ips, vp, &result);
95059512
if (!result) break;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[GH #399]
2+
Default-initialized local static constexpr variables in constant evaluation
3+
4+
In C++23 mode, a default-initialized local "static constexpr" variable of
5+
class type caused the constant evaluation of the enclosing function to fail.
6+
For example, with --c++23:
7+
8+
struct Q { int q = 1; };
9+
constexpr int f() { static constexpr Q q; return q.q; }
10+
static_assert(f() == 1); // Previously failed.
11+
12+
This is now fixed.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fe_only -DTEST_NUMBER=1 --c++23 Test_name.c

‎tests/tests/changes/gh-399.sft.cpp‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//type:fp
2+
//options:--c++23
3+
//remark:[GH #399] Constant evaluation with a default-initialized local
4+
//remark:static constexpr variable of class type
5+
6+
struct Q { int q = 1; };
7+
constexpr int default_init() { static constexpr Q q; return q.q; }
8+
static_assert(default_init() == 1); // Previously failed.
9+
constexpr int value_init() { static constexpr Q q{}; return q.q + 1; }
10+
static_assert(value_init() == 2);
11+
12+
struct R { int r = 3; constexpr R() {} };
13+
constexpr int user_ctor() {
14+
static constexpr R r;
15+
constexpr const R* p = &r;
16+
return p->r;
17+
}
18+
static_assert(user_ctor() == 3); // Previously failed.
19+
20+
template<typename T> constexpr int templ() {
21+
static constexpr T t;
22+
return t.q * 10;
23+
}
24+
static_assert(templ<Q>() == 10); // Previously failed.

0 commit comments

Comments
 (0)