Title
Insufficient base class restriction for pointer-to-member expression
Status
review
Section
7.6.4 [expr.mptr.oper]
Submitter
Hubert Tong

Created on 2022-06-04.00:00:00 last changed 17 months ago

Messages

Date: 2022-06-08.07:12:46

Suggested resolution:

Change in 7.6.4 [expr.mptr.oper] paragraph 4 as follows:

Abbreviating pm-expression.*cast-expression as E1.*E2, E1 is called the object expression. If the dynamic type of E1 does not contain the member to which E2 refers, Where the type of E2 is "pointer to member of T", C is the (unique) class of which the member to which E2 refers is a direct member, and B is the object of type T that either is the result of E1 or is the uniquely so-typed base subobject thereof, if B is neither of type C nor a base class subobject of an object of type C, then the behavior is undefined.
Date: 2022-06-04.00:00:00

Consider:

  struct A {};
  struct AA : A { int y; };
  struct B : A { int x; };
  struct C : AA, B {};

  constexpr int f(const A &a) {
    int A::*mp = static_cast<int A::*>(&B::x);
    return a.*mp;
  }

  extern char x[f(static_cast<const AA &>(C{{{}, 13}, {{}, 42}}))];
  extern char x[13];

Subclause 7.6.4 [expr.mptr.oper] paragraph 4 specifies:

Abbreviating pm-expression.*cast-expression as E1.*E2, E1 is called the object expression. If the dynamic type of E1 does not contain the member to which E2 refers, the behavior is undefined.

In the example, the dynamic type of a is C, which does contain B::x, and the undefined behavior provision does not trigger. Thus the call to f is required to yield 42; however common implementations produce 13. The behavior for this case ought to be undefined.

History
Date User Action Args
2023-06-20 19:34:52adminsetstatus: open -> review
2022-06-08 07:12:46adminsetmessages: + msg6845
2022-06-04 00:00:00admincreate