Bug 25342 - [4.0 Regression] internal compiler error: in lookup_member, at cp/search.c:1209
Summary: [4.0 Regression] internal compiler error: in lookup_member, at cp/search.c:1209
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.0.1
: P2 normal
Target Milestone: 4.1.0
Assignee: Mark Mitchell
URL:
Keywords: ice-on-valid-code, monitored, rejects-valid, wrong-code
Depends on:
Blocks:
 
Reported: 2005-12-10 23:57 UTC by Kai-Uwe Bux
Modified: 2007-02-03 16:06 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 3.3.3 4.1.0 4.1.1 4.1.2 4.2.0
Known to fail: 3.4.0 4.0.0
Last reconfirmed: 2005-12-11 00:31:42


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Kai-Uwe Bux 2005-12-10 23:57:18 UTC
g++ asked me to submit this report. It crashed on the following piece of code:

template < typename eval >
struct tpl_seq_search {

  typedef typename eval::enum_type  Enum;

  template < Enum first, Enum last >
  struct range {

    static void find () {
      range<first+1,last>::find();
    }
	
  };// range

  template < Enum val >
  struct range<val,val> {
	
    static void find () {}
	
  };// range

}; // tpl_bin_search
    
template < typename eval, typename eval::enum_type first, typename eval::enum_type last >
void
tpl_seq_search_from_to () {
  return( tpl_seq_search<eval>::template range<first,last>::find() );
}
  
struct xxx {

  typedef int enum_type;
  static enum_type const first = 0;
  static enum_type const last = 20;

};

int main ( void ) {
  tpl_seq_search_from_to<xxx,xxx::first,xxx::last>();
}

gcc> /added/pkg/gcc-4.0.2/usr/bin/g++ bug_20051208_01.cc 
bug_20051208_01.cc: In function 'void tpl_seq_search_from_to() [with eval = xxx, typename eval::enum_type first = 0, typename eval::enum_type last = 20]':
bug_20051208_01.cc:39:   instantiated from here
bug_20051208_01.cc:27: internal compiler error: in lookup_member, at cp/search.c:1209
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.



The specs are:

gcc> /added/pkg/gcc-4.0.2/usr/bin/g++ -v                 
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../gcc-4.0.2/configure --prefix=/added/pkg/gcc-4.0.2/usr
Thread model: posix
gcc version 4.0.2


Best

Kai-Uwe Bux
Comment 1 Andrew Pinski 2005-12-11 00:31:42 UTC
Confirmed reduced testcase:
template < typename eval >
struct tpl_seq_search {
  typedef typename eval::enum_type  Enum;
  template < Enum first, Enum last >
  struct range {
  };
  template < Enum val >
  struct range<val,val> {
  };
};
struct xxx {
  typedef int enum_type;
  tpl_seq_search<xxx>::range<0, 1> a;
};
Comment 2 Mark Mitchell 2005-12-11 05:47:09 UTC
Looking at it.
Comment 3 Andrew Pinski 2005-12-12 02:45:34 UTC
: Search converges between 2003-10-17-trunk (#379) and 2003-10-18-trunk (#380).
Comment 4 Mark Mitchell 2005-12-19 19:26:30 UTC
Should be fixed before release, if possible: P2.
Comment 5 Andrew Pinski 2006-01-14 06:01:47 UTC
Janis could you do a regression hunt on this bug?

Thanks,
Andrew
Comment 6 Janis Johnson 2006-01-16 20:34:47 UTC
A regression hunt on powerpc-linux using the testcase from comment #1 identified the following patch:

http://gcc.gnu.org/viewcvs?view=rev&rev=72611

r72611 | lerdsuwa | 2003-10-17 15:41:46 +0000 (Fri, 17 Oct 2003) | 13 lines
                                                                                
        PR c++/2513
        * decl.c (make_typename_type): Use dependent_type_p.
        (make_unbound_class_template): Likewise.
        * pt.c (instantiate_class_template): Increment
        processing_template_decl during substitution of template friend
        function.  Preincrement processing_template_decl rather than
        postincrement.
        (get_mostly_instantiated_function_type): Increment
        processing_template_decl during partial substitution of function
        type.
Comment 7 Mark Mitchell 2006-02-01 02:51:17 UTC
Subject: Bug 25342

Author: mmitchel
Date: Wed Feb  1 02:51:13 2006
New Revision: 110466

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=110466
Log:
	PR c++/25342
	* cp-tree.h (DECL_TEMPLATE_SPECIALIZATIONS): Revise
	documentation.
	* pt.c (determine_specialization): Use INNERMOST_TEMPLATE_PARMS,
	not TREE_VALUE.
	(instantiate_class_template): Simplify.
	(verify_class_unification): Remove.
	(unify): Document parameters.  Use INNERMOST_TEMPLATE_ARGS to
	permit multiple levels of template arguments.
	(more_specialized_class): Simplify.
	(get_class_bindings): Pass full arguments to unify.  Fold
	verify_class_unification into this function.  Return full
	arguments.
	(most_specialized_class): Adjust for changes to
	get_class_bindings.  Issue errors here for ambiguity.  Return the
	fully deduced arguments for the most specialized class, in
	addition to the partial specialization.
	PR c++/25342
	* g++.gd/template/partial4.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/template/partial4.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/cp-tree.h
    trunk/gcc/cp/pt.c
    trunk/gcc/testsuite/ChangeLog

Comment 8 Mark Mitchell 2006-02-01 02:55:49 UTC
Subject: Bug 25342

Author: mmitchel
Date: Wed Feb  1 02:55:45 2006
New Revision: 110467

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=110467
Log:
	PR c++/25342
	* cp-tree.h (DECL_TEMPLATE_SPECIALIZATIONS): Revise
	documentation.
	* pt.c (determine_specialization): Use INNERMOST_TEMPLATE_PARMS,
	not TREE_VALUE.
	(instantiate_class_template): Simplify.
	(verify_class_unification): Remove.
	(unify): Document parameters.  Use INNERMOST_TEMPLATE_ARGS to
	permit multiple levels of template arguments.
	(more_specialized_class): Simplify.
	(get_class_bindings): Pass full arguments to unify.  Fold
	verify_class_unification into this function.  Return full
	arguments.
	(most_specialized_class): Adjust for changes to
	get_class_bindings.  Issue errors here for ambiguity.  Return the
	fully deduced arguments for the most specialized class, in
	addition to the partial specialization.
	PR c++/25342
	* g++.gd/template/partial4.C: New test.

Added:
    branches/gcc-4_1-branch/gcc/testsuite/g++.dg/template/partial4.C
Modified:
    branches/gcc-4_1-branch/gcc/cp/ChangeLog
    branches/gcc-4_1-branch/gcc/cp/cp-tree.h
    branches/gcc-4_1-branch/gcc/cp/pt.c
    branches/gcc-4_1-branch/gcc/testsuite/ChangeLog

Comment 9 Mark Mitchell 2006-02-01 02:56:29 UTC
Fixed in 4.1.
Comment 10 Volker Reichelt 2006-08-04 21:17:14 UTC
The reduced testcase from comment #1 now compiles on the 4.0 branch.
However, the original testcase still causes hiccups (but no ICE):

bug.cc: In static member function 'static void tpl_seq_search<eval>::range<first, last>::find() [with typename eval::enum_type first = 498, typename eval::enum_type last = 20, eval = xxx]':
bug.cc:10: error: template instantiation depth exceeds maximum of 500 (use -ftemplate-depth-NN to increase the maximum) instantiating 'struct tpl_seq_search<xxx>::range<499, 20>'
bug.cc:10:   instantiated from 'static void tpl_seq_search<eval>::range<first, last>::find() [with typename eval::enum_type first = 498, typename eval::enum_type last = 20, eval = xxx]'
bug.cc:10:   instantiated from 'static void tpl_seq_search<eval>::range<first, last>::find() [with typename eval::enum_type first = 497, typename eval::enum_type last = 20, eval = xxx]'

[snip]

bug.cc:10:   instantiated from 'static void tpl_seq_search<eval>::range<first, last>::find() [with typename eval::enum_type first = 1, typename eval::enum_type last = 20, eval = xxx]'
bug.cc:10:   instantiated from 'static void tpl_seq_search<eval>::range<first, last>::find() [with typename eval::enum_type first = 0, typename eval::enum_type last = 20, eval = xxx]'
bug.cc:28:   instantiated from 'void tpl_seq_search_from_to() [with eval = xxx, typename eval::enum_type first = 0, typename eval::enum_type last = 20]'
bug.cc:40:   instantiated from here

bug.cc:10: error: incomplete type 'tpl_seq_search<xxx>::range<499, 20>' used in nested name specifier
Comment 11 Volker Reichelt 2006-08-04 21:39:59 UTC
Even worse, here's a modified example that produces wrong code on
the 4.0 branch:

====================================
struct A
{
  typedef int X;
};

template<typename T> struct B
{
  typedef typename T::X Y;

  template<Y y, Y> struct C
  {
    enum { i=1 };
  };

  template<Y y> struct C<y,y>
  {
    enum { i=0 };
  };
};

int main()
{
  return B<A>::C<0,0>().i;
}
====================================

The program should return 0, but returns 1 instead.
Comment 12 Gabriel Dos Reis 2007-02-03 16:06:56 UTC
Fixed in GCC-4.1.0.