Bug 72752 - [6 Regression] ICE: in retrieve_specialization, at cp/pt.c:1183
Summary: [6 Regression] ICE: in retrieve_specialization, at cp/pt.c:1183
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 6.1.0
: P2 normal
Target Milestone: 7.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2016-07-29 21:31 UTC by Michael
Modified: 2018-10-26 11:16 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work: 5.3.0, 7.0
Known to fail: 6.1.1
Last reconfirmed: 2016-07-31 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michael 2016-07-29 21:31:28 UTC
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 -----
Comment 1 Michael 2016-07-31 08:45:31 UTC
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 -----
Comment 2 Markus Trippelsdorf 2016-07-31 09:20:42 UTC
Confirmed for the very first testcase.
Only happens for gcc-6.

The other testcases are all ICEs on invalid.
Comment 3 Markus Trippelsdorf 2016-07-31 09:53:53 UTC
It was fixed on trunk by r236221. I guess a direct backport may be risky.
Jason?
Comment 4 Jason Merrill 2016-08-01 15:03:20 UTC
Yeah, that work isn't safe enough to backport.
Comment 5 Richard Biener 2016-08-22 08:28:45 UTC
GCC 6.2 is being released, adjusting target milestone.
Comment 6 Richard Biener 2016-08-22 08:29:48 UTC
GCC 6.2 is being released, adjusting target milestone.
Comment 7 Richard Biener 2016-08-22 08:52:15 UTC
GCC 6.2 is being released, adjusting target milestone.
Comment 8 Richard Biener 2016-08-22 08:53:38 UTC
GCC 6.2 is being released, adjusting target milestone.
Comment 9 Jakub Jelinek 2016-12-21 10:59:29 UTC
GCC 6.3 is being released, adjusting target milestone.
Comment 10 Richard Biener 2017-07-04 08:50:35 UTC
GCC 6.4 is being released, adjusting target milestone.
Comment 11 Benjamin Buch 2017-09-11 15:21:23 UTC
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)
Comment 12 Paolo Carlini 2018-03-01 16:44:41 UTC
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.
Comment 13 Benjamin Buch 2018-03-02 15:50:15 UTC
I will create a separate bug report in the next hour. (After testing the test cases against the current trunk.)
Comment 14 Benjamin Buch 2018-03-02 17:21:59 UTC
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()
{}
Comment 15 Paolo Carlini 2018-03-02 17:50:30 UTC
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!
Comment 16 Jakub Jelinek 2018-10-26 11:16:22 UTC
GCC 6 branch is being closed, fixed in 7.x.