Hi, On 07/09/2014 12:26 AM, Jason Merrill wrote:
I'd rather handle this in check_cv_quals_for_unify.
Yes, the below passes testing.
Thanks, Paolo. /////////////////////////
/cp 2014-07-09 Paolo Carlini <paolo.carl...@oracle.com> DR 1584 PR c++/57466 * pt.c (check_cv_quals_for_unify): Implement resolution, disregard cv-qualifiers of function types. /testsuite 2014-07-09 Paolo Carlini <paolo.carl...@oracle.com> DR 1584 PR c++/57466 * g++.dg/template/pr57466.C: New. * g++.dg/cpp0x/pr57466.C: Likewise. * g++.dg/template/unify6.C: Update.
Index: cp/pt.c =================================================================== --- cp/pt.c (revision 212385) +++ cp/pt.c (working copy) @@ -17189,6 +17189,11 @@ check_cv_quals_for_unify (int strict, tree arg, tr int arg_quals = cp_type_quals (arg); int parm_quals = cp_type_quals (parm); + /* DR 1584: cv-qualification of a deduced function type is + ignored; see 8.3.5 [dcl.fct]. */ + if (TREE_CODE (arg) == FUNCTION_TYPE) + return 1; + if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM && !(strict & UNIFY_ALLOW_OUTER_MORE_CV_QUAL)) { 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<typename T> + constexpr bool + is_pointer(const T*) + { return true; } + +template<typename T> + 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<class T> 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 212385) +++ testsuite/g++.dg/template/unify6.C (working copy) @@ -3,21 +3,20 @@ void Baz (); -template <typename T> void Foo1 (T *); // #1 -template <typename T> void Foo1 (T const *a) {a (1);} // #2 +template <typename T> void Foo1 (T *); +template <typename T> void Foo1 (T const *a) {a (1);} // { dg-error "too many arguments" } template <typename T> T const *Foo2 (T *); -template <typename T> void Foo3 (T *, T const * = 0); // { dg-message "note" } +template <typename T> 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); }