This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-10-26
[Accepted as a DR at the July, 2019 meeting.]
Consider an example like the following:
struct A { constexpr virtual int f() const { return 1; } }; struct B : A { constexpr virtual int f() const { return 2; } }; constexpr B b{}; constexpr A&& ref = (B)b; static_assert(ref.f() == 2, "");
Since the temporary bound to ref is non-const, it can be re-newed to something else, which would make the invocation ref.f() undefined behavior, which the interpreter is required to catch.
Presumably, ref.f() should not be a constant expression, and 7.7 [expr.const] paragraph 2 should have a bullet for invoking a virtual function of a non-const object unless its lifetime began within the evaluation of the constant expression.
Proposed resolution (March, 2019):
Add the following as a new bullet following 7.7 [expr.const] bullet 4.4:
An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (6.9.1 [intro.execution]), would evaluate one of the following expressions:
...
an invocation of an instantiated constexpr function or constexpr constructor that fails to satisfy the requirements for a constexpr function or constexpr constructor (9.2.6 [dcl.constexpr]);
an invocation of a virtual function (11.7.3 [class.virtual]) for an object unless
the object is usable in constant expressions or
its lifetime began within the evaluation of e;
an expression that would exceed the implementation-defined limits (see Clause Annex B [implimits]);
...