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
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; };
Looking at it.
: Search converges between 2003-10-17-trunk (#379) and 2003-10-18-trunk (#380).
Should be fixed before release, if possible: P2.
Janis could you do a regression hunt on this bug? Thanks, Andrew
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.
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
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
Fixed in 4.1.
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
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.
Fixed in GCC-4.1.0.