This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 114a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-04-18


2589. Context of access checks during constraint satisfaction checking

Section: 13.5.2.3  [temp.constr.atomic]     Status: review     Submitter: Jason Merrill     Date: 2019-10-02

Consider:

  template<class T> concept ctible = requires { T(); };

  class A {
    template <class T> friend struct B;
    A();
  };

  template <class T> struct B;
  template <ctible T> struct B<T> { T t; };
  B<A> b;  // #1

  template <class T> struct C { };
  template <ctible T> struct C<T> { T t; };
  C<A> c;  // #2

Should the context of instantiation be considered for satisfaction checking? If satisfaction checking were always performed in an unrelated context, neither partial specialization is used, and #1 would be ill-formed (because B is incomplete), but #2 would be well-formed. If the satisfaction checking were performed in the context of the constrained declaration, #1 would be well-formed and #2 would be ill-formed, no diagnostic required, because the validity of A() is different in that context. That rule, however, could also consider the context, in which case #2 would also be well-formed.

The decision affects the amount of caching that an implementation can perform.

Subclause 13.5.2.3 [temp.constr.atomic] paragraph 3 should be clarified one way or another:

To determine if an atomic constraint is satisfied, the parameter mapping and template arguments are first substituted into its expression. If substitution results in an invalid type or expression, the constraint is not satisfied. Otherwise, the lvalue-to-rvalue conversion (7.3.2 [conv.lval]) is performed if necessary, and E shall be a constant expression of type bool. The constraint is satisfied if and only if evaluation of E results in true. If, at different points in the program, the satisfaction result is different for identical atomic constraints and template arguments, the program is ill-formed, no diagnostic required.

Proposed resolution:

Change in 13.5.2.3 [temp.constr.atomic] paragraph 3 as follows:

To determine if an atomic constraint is satisfied, the parameter mapping and template arguments are first substituted into its expression. If substitution results in an invalid type or expression, the constraint is not satisfied; access checking is performed in the context in which the constraint-expression or requires-expression appears. Otherwise, the lvalue-to-rvalue conversion (7.3.2 [conv.lval]) is performed if necessary, and E shall be a constant expression of type bool. ...