The following program is reduced from the code in this question:
template <typename T, void (*)(T), typename = void>
struct S;
template <typename T, void (*f)(T)>
struct S<T, f, void> {};
S<int const, nullptr> s;
In all versions of GCC, in all language revisions, the specialization of S is chosen when s is instantiated.
In all versions of Clang, but only from C++17 onward, the primary template is chosen when instantiating s.
Some points I think worth noting are that the primary is never chosen if the instantiation is over <int, nullptr>, i.e. the first parameter is no longer int const. Also, the primary is never chosen if the signature of the function pointer in the second parameter doesn't contain T as the argument, i.e. if the second parameter is T (*)(), or void (*)(), say.
If this code isn't IFNDR, which compiler is correct? Is there some breaking change in the C++17 language revision?