[temp.constr.normal] p1.4 The implementations have a divergence for substitution in the normalization of a concept-id
Nobody has claimed this yet.
- Dominant language
- TeX
- Stars
- 221
- Forks
- 813
- Avg merge
- 16h 4m
- Merged PRs (30d)
- 36
Description
[temp.constr.normal] p1.4 says
The normal form of a concept-id
C<A1, A2, ..., An>is the normal form of the constraint-expression of C, after substitutingA1, A2, ..., Anfor C's respective template parameters in the parameter mappings in each atomic constraint. If any such substitution results in an invalid type or expression, the program is ill-formed; no diagnostic is required.
Consider this example:
template<typename T> concept A = T::value || true;
template<typename U> concept C = A<U*>;
template<class T>
requires C<T> void fun(T){}
int main(){
int a = 0;
fun<int&>(a);
}
In this case, the template parameter that appears in the atomic constraint is T, where the mapping is T↦ U*, and the template argument in concept-id C<int&> is int&, when undergoing the normalization of C<int&>, C's template parameter U that appears in the parameter mapping is substituted by int&, such substitution results in an invalid type int&*. By this logic, the program should be ill-formed. For this example, Clang rejects it but GCC accepts it and calls the specialization. Clang gave a kindly reminder:
<source>:2:37: note: because substituted constraint expression is ill-formed:
'type name' declared as a pointer to a reference of type 'int &'
@jensmaurer
Another case based on the above concept-id for which they have a divergence is
bool r = !C<int&>;
std::cout<< r;
GCC prints 0 while Clang prints 1.
The divergence might raise from the confusion mentioned in https://github.com/cplusplus/draft/issues/5389.
In summary of these two issues, [temp.constr.normal] p1.4 might be changed to
The normal form of a concept-id
C<A1, A2, ..., An>is the normal form of the constraint-expression of C, after substitutingA1, A2, ..., Anfor C's respective template parameters that appear in concept-ids(if any) inC's constraint-expression and mapping C's respective template parameters that appear inC's constraint-expression toA1, A2, ..., An. If any such substitution results in an invalid type or expression, the program is ill-formed; no diagnostic is required.
This modification conforms to the definition of parameter mapping
An atomic constraint is formed from an expression E and a mapping from the template parameters that appear within E to template arguments that are formed via substitution during constraint normalization in the declaration of a constrained entity (and, therefore, can involve the unsubstituted template parameters of the constrained entity), called the parameter mapping ([temp.constr.decl]).
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with [temp.constr.normal] p1.4 and the parameter-mapping definition quoted in the issue. Compare the two linked compiler examples, including the C<int&> normalization and negation cases, against the proposed wording. Done means resolving the GCC/Clang divergence and agreeing on the corresponding draft text.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Documentation
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100