Consider this code:
#include <type_traits>
#include <iostream>
template <class T> concept bool C1 = std::is_same<T, int>::value;
template <class T> concept bool C2 =
C1<decltype(std::declval<T>() + std::declval<T>())>;
struct A {};
int main() {
std::cout << C2<int>;
std::cout << C2<A>;
return 0;
}
GCC compiles it fine and prints 10.
But §14.10.1.2 Predicate constraints [temp.constr.pred] of N4553 says
A predicate constraint is a constraint that evaluates a constant expression E (5.19).
and then
After substitution, E shall have type bool.
Since C1<decltype(std::declval<A>() + std::declval<A>())>
is a substitution failure, rather than having type bool, does that mean the program should be ill-formed?