The use_partial_inst_tmpl code in lookup_template_class didn't work as intended because when converting the ref-to-fn parameter to the same type we wrapped it in a couple of extra NOP_EXPR.
Tested x86_64-pc-linux-gnu, applying to trunk and 7.
commit ac1c39476b98ab4b6b52952df5baa07cf923d4e0 Author: Jason Merrill <ja...@redhat.com> Date: Fri Feb 16 13:34:24 2018 -0500 PR c++/82664 - ICE with reference to function template parm. * pt.c (convert_nontype_argument_function): Avoid obfuscationg NOP_EXPRs. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 268cfe5a454..89790717eca 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6143,7 +6143,12 @@ convert_nontype_argument_function (tree type, tree expr, accept: if (TREE_CODE (type) == REFERENCE_TYPE) - fn = build_address (fn); + { + if (REFERENCE_REF_P (fn)) + fn = TREE_OPERAND (fn, 0); + else + fn = build_address (fn); + } if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (fn))) fn = build_nop (type, fn); diff --git a/gcc/testsuite/g++.dg/template/nontype-fn1.C b/gcc/testsuite/g++.dg/template/nontype-fn1.C new file mode 100644 index 00000000000..12d29a91a54 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype-fn1.C @@ -0,0 +1,11 @@ +// PR c++/82664 + +template < typename > struct target_disambiguator; +template < typename R, typename A1 > struct target_disambiguator< R(A1) > { + typedef A1 type; + template < R (&)() > struct layout; +}; + +int main() { + typedef target_disambiguator< void (int) > ::type target_type ; +}