The following code generates an ice: ----- 8< ---------- 8< ---------- 8< ----- 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() {} ----- >8 ---------- >8 ---------- >8 ----- Version 5.3.0 compiles the above code successfully. This is possibly related with bug #66564. The following code generates an ice for both versions: ----- 8< ---------- 8< ---------- 8< ----- template< typename > struct Outer { template< typename > struct Inner; }; template<> template< typename _T_ > class Outer< _T_ >::Inner< _T_ > {}; template struct Outer< int >::Inner< int >; ----- >8 ---------- >8 ---------- >8 -----
When it is explicitly specified to use a default template argument the code is compiled successfully: ----- 8< ---------- 8< ---------- 8< ----- 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() {} ----- >8 ---------- >8 ---------- >8 ----- Here is a variation for one more test case: ICE generated: ----- 8< ---------- 8< ---------- 8< ----- 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() {} ----- >8 ---------- >8 ---------- >8 ----- Successfully passed: ----- 8< ---------- 8< ---------- 8< ----- 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() {} ----- >8 ---------- >8 ---------- >8 -----
Confirmed for the very first testcase. Only happens for gcc-6. The other testcases are all ICEs on invalid.
It was fixed on trunk by r236221. I guess a direct backport may be risky. Jason?
Yeah, that work isn't safe enough to backport.
GCC 6.2 is being released, adjusting target milestone.
GCC 6.3 is being released, adjusting target milestone.
GCC 6.4 is being released, adjusting target milestone.
template< typename > struct Outer { template< typename > struct Inner; }; template<> template< typename _T_ > class Outer< _T_ >::Inner< _T_ > {}; template struct Outer< int >::Inner< int >; This test case still fails in Trunk: $ g++ gcc-test.cpp gcc-test.cpp:10:21: internal compiler error: in retrieve_specialization, at cp/pt.c:1189 class Outer< _T_ >::Inner< _T_ > ^~~~~~~~~~~~ 0x63457f retrieve_specialization ../../gcc/gcc/cp/pt.c:1186 0xa6445e tsubst_template_decl ../../gcc/gcc/cp/pt.c:12477 0xa5fe7e tsubst_decl ../../gcc/gcc/cp/pt.c:12646 0xa5a097 tsubst(tree_node*, tree_node*, int, tree_node*) ../../gcc/gcc/cp/pt.c:13538 0xa4edad most_specialized_partial_spec ../../gcc/gcc/cp/pt.c:22160 0xa77278 instantiate_class_template_1 ../../gcc/gcc/cp/pt.c:10330 0xa77278 instantiate_class_template(tree_node*) ../../gcc/gcc/cp/pt.c:10898 0xabc5ad complete_type(tree_node*) ../../gcc/gcc/cp/typeck.c:136 0xa72c0e do_type_instantiation(tree_node*, tree_node*, int) ../../gcc/gcc/cp/pt.c:22425 0xa280fb cp_parser_explicit_instantiation ../../gcc/gcc/cp/parser.c:16430 0xa2f181 cp_parser_declaration ../../gcc/gcc/cp/parser.c:12655 0xa2f56b cp_parser_declaration_seq_opt ../../gcc/gcc/cp/parser.c:12579 0xa2f89a cp_parser_translation_unit ../../gcc/gcc/cp/parser.c:4387 0xa2f89a c_parse_file() ../../gcc/gcc/cp/parser.c:38799 0xb29786 c_common_parse_file() ../../gcc/gcc/c-family/c-opts.c:1106 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. $ g++ --version g++ (GCC) 8.0.0 20170911 (experimental)
Because of Comment #11 this bug is currently misleading: the original issue was a regression which doesn't affect anymore 7 and 8, but Comment 11 is still an issue everywhere. Probably we should have a separate bug for it.
I will create a separate bug report in the next hour. (After testing the test cases against the current trunk.)
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() {}
Thanks for the new bug. Note that this bug is marked as [6 Regression] and still open, thus isn't surprising at all that some or even all the testcases here fail in 6, actually it's expected. If you have testcases failing in 7 or 8, please open new bugs, for clarity. Thanks a lot again for your help!
GCC 6 branch is being closed, fixed in 7.x.