Title
Constexpr virtual functions and temporary objects
Status
cd5
Section
7.7 [expr.const]
Submitter
Daveed Vandevoorde

Created on 2019-02-08.00:00:00 last changed 40 months ago

Messages

Date: 2019-03-15.00:00:00

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]);

  • ...

Date: 2019-07-15.00:00:00

[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.

History
Date User Action Args
2020-12-15 00:00:00adminsetmessages: + msg6390
2019-02-08 00:00:00admincreate