Title
Incorrect cases of odr-use
Status
cd5
Section
6.3 [basic.def.odr]
Submitter
Hubert Tong

Created on 2015-02-11.00:00:00 last changed 40 months ago

Messages

Date: 2019-01-15.00:00:00

Proposed resolution (January, 2019):

  1. Change 6.3 [basic.def.odr] bullet 2.4 as follows:

  2. An expression is potentially evaluated unless it is an unevaluated operand (7.2 [expr.prop]) or a subexpression thereof. The set of potential results of an expression e is defined as follows:

    • ...

    • If e is a pointer-to-member expression (7.6.4 [expr.mptr.oper]) whose second operand is a constant expression, the set contains the potential results of the object expression.

    • ...

    • Otherwise, the set is empty.

  3. Change 6.3 [basic.def.odr] paragraph 4, converting the running text into bullets, as follows:

  4. A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless applying the lvalue-to-rvalue conversion (7.3.2 [conv.lval]) to x yields a constant expression (7.7 [expr.const]) that does not invoke a function other than a trivial special member function (11.4.4 [special]) and, if x is an object,

    • x is a reference that is usable in constant expressions (7.7 [expr.const]), or

    • x is a variable of non-reference type that is usable in constant expressions and has no mutable subobjects, and ex is an element of the set of potential results of an expression e, where either of non-volatile-qualified non-class type to which the lvalue-to-rvalue conversion (7.3.2 [conv.lval]) is applied to e, or e is

    • x is a variable of non-reference type, and e is an element of the set of potential results of a discarded-value expression (7.2 [expr.prop]) to which the lvalue-to-rvalue conversion is not applied.

    This resolution also resolves issues 2103 and 2170.

Date: 2019-02-15.00:00:00

[Accepted as a DR at the February, 2019 meeting.]

The resolution of issue 1741 was not intended to cause odr-use to occur in cases where it did not do so previously. However, in an example like

  extern int globx;
  int main() {
    const int &x = globx;
    struct A {
     const int *foo() {
       return &x;
     }
    } a;
    return *a.foo();
  }

x satisfies the requirements for appearing in a constant expression, but applying the lvalue-to-rvalue converstion to x does not yield a constant expression. Similarly,

  struct A {
    int q;
    constexpr A(int q) : q(q) { }
    constexpr A(const A &a) : q(a.q * 2) { }
  };

  int main(void) {
    constexpr A a(42);
    constexpr int aq = a.q;
    struct Q {
     int foo() { return a.q; }
    } q;
    return q.foo();
  }

a satisfies the requirements for appearing in a constant expression, but applying the lvalue-to-rvalue conversion to a invokes a non-trivial function.

History
Date User Action Args
2020-12-15 00:00:00adminsetmessages: + msg6347
2020-12-15 00:00:00adminsetstatus: drafting -> cd5
2017-02-06 00:00:00adminsetstatus: open -> drafting
2015-02-11 00:00:00admincreate