https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96821

--- Comment #7 from Patrick Palka <ppalka at gcc dot gnu.org> ---
(In reply to Daniil Dudkin from comment #5)
> (In reply to Patrick Palka from comment #4)
> > GCC's behaviour is correct, I think.  Since the concept constant_expression
> > doesn't use its template parameter, the normal form of foo's associated
> > constraint is just 'true (with an empty parameter mapping)', so the
> > satisfaction value of with_value_constant<T> for any T is trivially true and
> > independent of T.
> 
> 
> No, I don't think that GCC behaviour is correct. 
> 
> http://eel.is/c++draft/temp.constr#atomic-3
> 
> > If substitution results in an invalid type or expression, the constraint is 
> > not satisfied.

'Substitution' here refers to substitution into the atomic constraints of a
constraint-expression, not into the constraint-expression directly.  Atomic
constraints are formed via constraint normalization.  In the case of
with_value_constant<T>, normalization of this constraint-expression yields the
single atomic constraint 'true (with an empty parameter mapping)' as per
[temp.constr.atomic]/1 and [temp.constr.normal].  The substitution
'T=WithNonConstant' into this atomic constraint will never fail, because the
atomic constraint doesn't depend on any template parameters.

> 
> The substitution with_value_constant<WithNotConstant::value> results in an
> invalid expression because WithNotConstant::value is not a constant
> expression, so it cannot be used as a non-type template argument. That means
> with_value_constant<WithNotConstant::value> should be false regardless how
> with_value_constant is defined.

As mentioned before, you need to make the concept constant_expression depend on
its template parameter so that normalization doesn't throw away the 'T::value'
template argument inside the definition of with_value_constant.

(In reply to Alexander Zaitsev from comment #6)
> Any updates on the issue? Such behaviour is strange too since Clang and MSVC
> have a different opinion from GCC for the code.

I think GCC is behaving correctly here.

Reply via email to