https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72752
--- Comment #14 from Benjamin Buch <benni.buch at gmail dot com> --- The test case from comment 11 is now bug 84678. The other 4 test cases are known to successfully compile on GCC 6 and GCC 7 branch and current trunk (GCC 8). They are also known to compile with the current GCC 5 from Ubuntu 16.04: $ g++-5 --version g++-5 (Ubuntu 5.4.1-2ubuntu1~16.04) 5.4.1 20160904 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. But the test cases 1 and 3 still trigger an ICE on current GCC 6 branch! $ g++-6 -c main1.cpp main1.cpp: In substitution of 'template<class> template<class> static void A< <template-parameter-1-1> >::foo() [with <template-parameter-2-1> = <missing>; <template-parameter-1-1> = void]': main1.cpp:13:13: required from here main1.cpp:13:13: internal compiler error: in retrieve_specialization, at cp/pt.c:1183 test(foo); ^ 0x5bbd5b retrieve_specialization ../../gcc/gcc/cp/pt.c:1180 0x5d214e instantiate_template_1 ../../gcc/gcc/cp/pt.c:17449 0x5d214e instantiate_template(tree_node*, tree_node*, int) ../../gcc/gcc/cp/pt.c:17566 0x5d8e0d fn_type_unification(tree_node*, tree_node*, tree_node*, tree_node* const*, unsigned int, tree_node*, unification_kind_t, int, bool, bool) ../../gcc/gcc/cp/pt.c:17925 0x5e7a5e resolve_address_of_overloaded_function ../../gcc/gcc/cp/class.c:8194 0x5869c1 standard_conversion ../../gcc/gcc/cp/call.c:1106 0x58bc17 implicit_conversion ../../gcc/gcc/cp/call.c:1804 0x58d310 add_function_candidate ../../gcc/gcc/cp/call.c:2121 0x58dfcf add_candidates ../../gcc/gcc/cp/call.c:5363 0x590731 perform_overload_resolution ../../gcc/gcc/cp/call.c:4034 0x591b2e build_new_function_call(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool, int) ../../gcc/gcc/cp/call.c:4111 0x669aea finish_call_expr(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool, bool, int) ../../gcc/gcc/cp/semantics.c:2454 0x61b672 cp_parser_postfix_expression ../../gcc/gcc/cp/parser.c:6915 0x619cea cp_parser_unary_expression ../../gcc/gcc/cp/parser.c:7999 0x621b47 cp_parser_cast_expression ../../gcc/gcc/cp/parser.c:8676 0x6220dd cp_parser_binary_expression ../../gcc/gcc/cp/parser.c:8777 0x6227e0 cp_parser_assignment_expression ../../gcc/gcc/cp/parser.c:9064 0x624a8a cp_parser_expression ../../gcc/gcc/cp/parser.c:9233 0x624fdf cp_parser_expression_statement ../../gcc/gcc/cp/parser.c:10696 0x630b4f cp_parser_statement ../../gcc/gcc/cp/parser.c:10547 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <http://gcc.gnu.org/bugs.html> for instructions. $ g++-6 -c main3.cpp main3.cpp: In substitution of 'template<class> template<class> static void A< <template-parameter-1-1> >::foo1() [with <template-parameter-2-1> = <missing>; <template-parameter-1-1> = void]': main3.cpp:14:20: required from here main3.cpp:14:20: internal compiler error: in retrieve_specialization, at cp/pt.c:1183 test(foo1, foo2); ^ 0x5bbd5b retrieve_specialization ../../gcc/gcc/cp/pt.c:1180 0x5d214e instantiate_template_1 ../../gcc/gcc/cp/pt.c:17449 0x5d214e instantiate_template(tree_node*, tree_node*, int) ../../gcc/gcc/cp/pt.c:17566 0x5d8e0d fn_type_unification(tree_node*, tree_node*, tree_node*, tree_node* const*, unsigned int, tree_node*, unification_kind_t, int, bool, bool) ../../gcc/gcc/cp/pt.c:17925 0x5e7a5e resolve_address_of_overloaded_function ../../gcc/gcc/cp/class.c:8194 0x5869c1 standard_conversion ../../gcc/gcc/cp/call.c:1106 0x58bc17 implicit_conversion ../../gcc/gcc/cp/call.c:1804 0x58d310 add_function_candidate ../../gcc/gcc/cp/call.c:2121 0x58dfcf add_candidates ../../gcc/gcc/cp/call.c:5363 0x590731 perform_overload_resolution ../../gcc/gcc/cp/call.c:4034 0x591b2e build_new_function_call(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool, int) ../../gcc/gcc/cp/call.c:4111 0x669aea finish_call_expr(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool, bool, int) ../../gcc/gcc/cp/semantics.c:2454 0x61b672 cp_parser_postfix_expression ../../gcc/gcc/cp/parser.c:6915 0x619cea cp_parser_unary_expression ../../gcc/gcc/cp/parser.c:7999 0x621b47 cp_parser_cast_expression ../../gcc/gcc/cp/parser.c:8676 0x6220dd cp_parser_binary_expression ../../gcc/gcc/cp/parser.c:8777 0x6227e0 cp_parser_assignment_expression ../../gcc/gcc/cp/parser.c:9064 0x624a8a cp_parser_expression ../../gcc/gcc/cp/parser.c:9233 0x624fdf cp_parser_expression_statement ../../gcc/gcc/cp/parser.c:10696 0x630b4f cp_parser_statement ../../gcc/gcc/cp/parser.c:10547 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <http://gcc.gnu.org/bugs.html> for instructions. $ g++-6 --version g++ (GCC) 6.4.1 20180302 Copyright (C) 2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Test case 1: typedef void (*foo_t)(); void test(foo_t) {} template< typename > struct A { template< typename = void > static void foo(); void bar() { test(foo); } template< typename > void baz() { test(foo); } }; template< typename _T_ > template< typename > void A< _T_ >::foo() {} Test case 2: typedef void (*foo_t)(); void test(foo_t) {} template< typename > struct A { template< typename = void > static void foo(); void bar() { test(foo<>); } template< typename > void baz() { test(foo<>); } }; template< typename _T_ > template< typename > void A< _T_ >::foo() {} Test case 3: typedef void (*foo_t)(); void test(foo_t, foo_t) {} template< typename > struct A { template< typename = void > static void foo1(); template< typename = void > static void foo2(); void bar() { test(foo1, foo2); } template< typename > void baz() { test(foo1, foo2); } }; template< typename _T_ > template< typename > void A< _T_ >::foo1() {} template< typename _T_ > template< typename > void A< _T_ >::foo2() {} Test case 4: typedef void (*foo_t)(); void test(foo_t, foo_t) {} template< typename > struct A { template< typename = void > static void foo1(); template< typename = void > static void foo2(); void bar() { test(foo1, foo2<>); } template< typename > void baz() { test(foo1<>, foo2); } }; template< typename _T_ > template< typename > void A< _T_ >::foo1() {} template< typename _T_ > template< typename > void A< _T_ >::foo2() {}