Index: cp/pt.c =================================================================== --- cp/pt.c (revision 212347) +++ cp/pt.c (working copy) @@ -17831,8 +17831,13 @@ unify (tree tparms, tree targs, tree parm, tree ar a match unless we are allowing additional qualification. If ARG is `const int' and PARM is just `T' that's OK; that binds `const int' to `T'. */ - if (!check_cv_quals_for_unify (strict_in | UNIFY_ALLOW_LESS_CV_QUAL, - arg, parm)) + + /* DR 1584: cv-qualification of a deduced function type is + ignored; see 8.3.5 [dcl.fct]. */ + if (TREE_CODE (arg) != FUNCTION_TYPE + && !check_cv_quals_for_unify (strict_in + | UNIFY_ALLOW_LESS_CV_QUAL, + arg, parm)) return unify_cv_qual_mismatch (explain_p, parm, arg); /* Consider the case where ARG is `const volatile int' and Index: testsuite/g++.dg/cpp0x/pr57466.C =================================================================== --- testsuite/g++.dg/cpp0x/pr57466.C (revision 0) +++ testsuite/g++.dg/cpp0x/pr57466.C (working copy) @@ -0,0 +1,18 @@ +// PR c++/57466 +// { dg-do compile { target c++11 } } + +template + constexpr bool + is_pointer(const T*) + { return true; } + +template + constexpr bool + is_pointer(const T&) + { return false; } + +using F = void(); + +constexpr F* f = nullptr; + +static_assert( is_pointer(f), "function pointer is a pointer" ); Index: testsuite/g++.dg/template/pr57466.C =================================================================== --- testsuite/g++.dg/template/pr57466.C (revision 0) +++ testsuite/g++.dg/template/pr57466.C (working copy) @@ -0,0 +1,8 @@ +// DR 1584, PR c++/57466 + +template void f2(const T*); +void g2(); + +void m() { + f2(g2); // OK: cv-qualification of deduced function type ignored +} Index: testsuite/g++.dg/template/unify6.C =================================================================== --- testsuite/g++.dg/template/unify6.C (revision 212347) +++ testsuite/g++.dg/template/unify6.C (working copy) @@ -3,21 +3,20 @@ void Baz (); -template void Foo1 (T *); // #1 -template void Foo1 (T const *a) {a (1);} // #2 +template void Foo1 (T *); +template void Foo1 (T const *a) {a (1);} // { dg-error "too many arguments" } template T const *Foo2 (T *); -template void Foo3 (T *, T const * = 0); // { dg-message "note" } +template void Foo3 (T *, T const * = 0); void Bar () { - Foo1 (&Baz); // #1 + Foo1 (&Baz); // { dg-message "required from here" } Foo2 (&Baz); Foo3 (&Baz); - Foo3 (&Baz, &Baz); // { dg-error "no matching function" "" } - // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 21 } + Foo3 (&Baz, &Baz); }