Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/interpret.c
Original file line number Diff line number Diff line change
Expand Up @@ -9500,6 +9500,13 @@ loop body push a work item for it and continue in a later phase.
{ a_dynamic_init_ptr dip = stmt->variant.dynamic_init;
a_variable_ptr vp = dip->variable;
a_byte *var_storage;
if (var_has_static_or_thread_storage_duration(vp)) {
/* A local static variable (e.g., a default-initialized one of
class type) that is usable in constant expressions (see
stmk_decl below): its value is obtained when it is
referenced. */
break;
} /* if */
/* Allocate and bind storage for the variable. */
var_storage = do_constexpr_alloc_variable(ips, vp, &result);
if (!result) break;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[GH #399]
Default-initialized local static constexpr variables in constant evaluation

In C++23 mode, a default-initialized local "static constexpr" variable of
class type caused the constant evaluation of the enclosing function to fail.
For example, with --c++23:

struct Q { int q = 1; };
constexpr int f() { static constexpr Q q; return q.q; }
static_assert(f() == 1); // Previously failed.

This is now fixed.
1 change: 1 addition & 0 deletions tests/tests/changes/.gh-399.rto/default.1.1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fe_only -DTEST_NUMBER=1 --c++23 Test_name.c
23 changes: 23 additions & 0 deletions tests/tests/changes/gh-399.sft.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//type:fp
//options:--c++23
//remark:Default-initialized local static constexpr in constant evaluation

struct Q { int q = 1; };
constexpr int default_init() { static constexpr Q q; return q.q; }
static_assert(default_init() == 1); // Previously failed.
constexpr int value_init() { static constexpr Q q{}; return q.q + 1; }
static_assert(value_init() == 2);

struct R { int r = 3; constexpr R() {} };
constexpr int user_ctor() {
static constexpr R r;
constexpr const R* p = &r;
return p->r;
}
static_assert(user_ctor() == 3); // Previously failed.

template<typename T> constexpr int templ() {
static constexpr T t;
return t.q * 10;
}
static_assert(templ<Q>() == 10); // Previously failed.
Loading