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

2024-09-25

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