In this testcase, instantiate_type resolves the overload, but the result is a pointer to the wrong class; we need to then try to convert it to the desired type in order to get the diagnostic we want.
Tested x86_64-pc-linux-gnu, applying to trunk and 7.
commit 9248f1e42712d3edfc5447e6df371b1458bc4f5e Author: Jason Merrill <ja...@redhat.com> Date: Thu Jun 15 18:17:19 2017 -0400 PR c++/80639 - ICE with invalid PMF initialization. PR c++/80043 - ICE with -fpermissive * typeck.c (convert_for_assignment): Recurse when instantiate_type returns without an error. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 05b4fbb..0f22e64 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -8590,9 +8590,10 @@ convert_for_assignment (tree type, tree rhs, if (rhstype == unknown_type_node) { tree r = instantiate_type (type, rhs, tf_warning_or_error); - /* -fpermissive might allow this. */ + /* -fpermissive might allow this; recurse. */ if (!seen_error ()) - return r; + return convert_for_assignment (type, r, errtype, fndecl, + parmnum, complain, flags); } else if (fndecl) error ("cannot convert %qH to %qI for argument %qP to %qD", diff --git a/gcc/testsuite/g++.dg/template/ptrmem31.C b/gcc/testsuite/g++.dg/template/ptrmem31.C new file mode 100644 index 0000000..5c66b72 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem31.C @@ -0,0 +1,23 @@ +// PR c++/80639 +// { dg-do compile { target c++14 } } + +template < typename > struct A; + +struct B +{ + template < int > void m (); + template < int > struct K { static void n (); }; + void p () { K < 0 >::n (); } +}; + +template <> struct A < B > +{ + using T = void (A::*)(); + template < int u > static constexpr T h = &B::m < u >; // { dg-error "cannot convert" } +}; + +template < int v > void B::K < v >::n () +{ + using S = A < B >; + S::h < 0 >; +}