Bug 13289

Summary: [3.3 regression] ICE in regenerate_decl_from_template on recursive template
Product: gcc Reporter: gianni
Component: c++Assignee: Kriang Lerdsuwanakij <lerdsuwa>
Status: RESOLVED FIXED    
Severity: critical CC: gcc-bugs, reichelt
Priority: P2 Keywords: ice-on-valid-code, monitored, patch
Version: 3.3.1   
Target Milestone: 3.3.3   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2003-12-04 17:10:59

Description gianni 2003-12-03 23:50:40 UTC
I can understand why this code has problems - it is recursive, I need to find a
way to make it not be so !  But the compiler spits out an "internal compiler
error" that probably needs a look at.

template <typename T, T N>
struct bit_count_templ
{
        static const T bit_count;
};

template <typename T, T N>
const T bit_count_templ<T,N>::bit_count = 1 + ( N == 0 ? 0 : bit_count_templ<T,
N & ( N -1 ) >::bit_count );


#include <iostream>

int main()
{
        std::cout << bit_count_templ<long,0x256500LL>::bit_count;
}

g++ -Wreturn-type -W -Wpointer-arith -pipe -ggdb3 -fcheck-new -fPIC 
-D_POSIX_THREADS -D_POSIX_THREAD_SAFE_FUNCTIONS -D_REENTRANT  templ_bitcount.cpp
  -o templ_bitcount
templ_bitcount.cpp: In instantiation of `const long int bit_count_templ<long
int, 0>::bit_count':
templ_bitcount.cpp:10:   instantiated from `const long int bit_count_templ<long
int, 0>::bit_count'
templ_bitcount.cpp:10:   instantiated from `const long int bit_count_templ<long
int, 2097152>::bit_count'
templ_bitcount.cpp:10:   instantiated from `const long int bit_count_templ<long
int, 2359296>::bit_count'
templ_bitcount.cpp:10:   instantiated from `const long int bit_count_templ<long
int, 2424832>::bit_count'
templ_bitcount.cpp:10:   instantiated from `const long int bit_count_templ<long
int, 2441216>::bit_count'
templ_bitcount.cpp:10:   instantiated from `const long int bit_count_templ<long
int, 2449408>::bit_count'
templ_bitcount.cpp:10:   instantiated from `const long int bit_count_templ<long
int, 2450432>::bit_count'
templ_bitcount.cpp:10:   instantiated from `const long int bit_count_templ<long
int, 2450688>::bit_count'
templ_bitcount.cpp:17:   instantiated from here
templ_bitcount.cpp:10: internal compiler error: in 
   regenerate_decl_from_template, at cp/pt.c:10131
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
Comment 1 Wolfgang Bangerth 2003-12-04 17:10:57 UTC
Confirmed. Since it's an ICE after error, it gets low priority. 
 
The funny thing is: gcc 3.2.3 silently accepts the code, whereas 
2.95 gets all confused and generates really nonsensical error 
messages :-) This all means, though, that this is also not a regression. 
 
W. 
Comment 2 Wolfgang Bangerth 2003-12-04 17:15:52 UTC
This is somewhat simpler to understand: 
------------------------ 
template <int N> struct S { 
    static const int C; 
}; 
 
template <int N> 
const int S<N>::C = S<(N+1)%2>::C; 
 
template struct S<1>; 
------------------------- 
 
g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ -c x.cc 
x.cc: In instantiation of `const int S<1>::C': 
x.cc:6:   instantiated from `const int S<0>::C' 
x.cc:6:   instantiated from `const int S<1>::C' 
x.cc:8:   instantiated from here 
x.cc:6: internal compiler error: in regenerate_decl_from_template, at cp/
pt.c:10771 
 
Comment 3 Volker Reichelt 2003-12-04 17:26:49 UTC
First, here's a slightly different example that triggers the ICE:

==============================================================
template <int> struct A
{
    static const int i;
};

template <int N> const int A<N>::i = ( N ? A<N&0>::i : 0 );

int j=A<1>::i;
==============================================================

x.cc: In instantiation of `const int A<0>::i':
x.cc:10:   instantiated from `const int A<0>::i'
x.cc:10:   instantiated from `const int A<1>::i'
x.cc:12:   instantiated from here
x.cc:10: internal compiler error: in regenerate_decl_from_template, at
cp/pt.c:10771
Please submit a full bug report, [etc.]

If I replace "N&0" by "0" in the example above, I get the following
error message:

x.cc:10: error: template instantiation depth exceeds maximum of 500 (use
-ftemplate-depth-NN to increase the maximum) instantiating `A<0>::i'
x.cc:10:   instantiated from `const int A<0>::i'
[repeated ~1000 times]
x.cc:12:   instantiated from here


Second, I don't agree with Wolfgang. This code looks valid to me
(and is accepted by gcc 3.0 - 3.2.3 as well as icc 7 and Comeau).
Thus, we have a regression here and therefore severity "critical".
Comment 4 Wolfgang Bangerth 2003-12-04 19:54:13 UTC
The code I gave is certainly not valid, since it involves a recursive 
dependence on templates. 
 
For your code, one may argue that it is only valid if the compiler is 
allowed to skip evaluating the unused arm of a conditional expression. 
When you write 
  A<N>::i = (N ? A<N&0> : 0) 
then 
- if N==0: the code is recursive if we try to evaluate the first part 
  of the conditional, since it again involves A<0>::i, which we are 
  about to initialize 
- if N!=0, then we get into the N==0 case on the next iteration. 
I'm not sure if we are allowed to skip evaluation. Someone will be able to 
point to the right place in the standard, though, I guess. 
 
In either case, I don't care too much: raising the priority increases chances 
to have the bug fixed, which I believe is always good :-) 
 
W. 
Comment 5 Kriang Lerdsuwanakij 2003-12-19 14:31:18 UTC
Working on a patch.
Comment 6 Kriang Lerdsuwanakij 2003-12-24 15:14:46 UTC
Patch submitted:
  http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02046.html

For 3.3.3 this is a complete fix.  There is an additional
regression to deal with in GCC 3.4 so it's only a partial 
bugfix there.
Comment 7 GCC Commits 2003-12-29 11:00:40 UTC
Subject: Bug 13289

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	lerdsuwa@gcc.gnu.org	2003-12-29 11:00:36

Modified files:
	gcc/cp         : ChangeLog semantics.c 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/g++.dg/parse: nontype1.C 

Log message:
	PR c++/13289
	* semantics.c (finish_id_expression): Only check if the type of
	a template argument is integral or enumeration when it is not
	dependent.
	
	* g++.dg/parse/nontype1.C: New test.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.3839&r2=1.3840
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/semantics.c.diff?cvsroot=gcc&r1=1.379&r2=1.380
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.3317&r2=1.3318
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/parse/nontype1.C.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 8 Kriang Lerdsuwanakij 2003-12-29 11:02:44 UTC
The extra regression in 3.4 is fixed.  Now we only have 
the original problem left together with the patch 
(still waiting for an approval):

  http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02046.html

Comment 9 GCC Commits 2004-01-12 20:10:24 UTC
Subject: Bug 13289

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	pinskia@gcc.gnu.org	2004-01-12 20:10:20

Modified files:
	gcc/cp         : ChangeLog pt.c 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/g++.dg/template: instantiate6.C 

Log message:
	2004-01-12  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
	
	PR c++/13289
	* pt.c (instantiate_decl): Set DECL_TEMPLATE_INSTANTIATED before
	calling regenerate_decl_from_template.
	2004-01-12  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
	
	PR c++/13289
	* g++.dg/template/instantiate6.C: New test.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.3869&r2=1.3870
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/pt.c.diff?cvsroot=gcc&r1=1.811&r2=1.812
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.3365&r2=1.3366
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/instantiate6.C.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 10 Andrew Pinski 2004-01-12 20:11:33 UTC
Fixed for 3.4 at least.
Comment 11 GCC Commits 2004-01-21 03:26:09 UTC
Subject: Bug 13289

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-3_3-branch
Changes by:	gdr@gcc.gnu.org	2004-01-21 03:26:07

Modified files:
	gcc/cp         : ChangeLog pt.c 
Added files:
	gcc/testsuite/g++.dg/template: instantiate6.C 

Log message:
	2004-01-20  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
	
	PR c++/13289
	* pt.c (instantiate_decl): Set DECL_TEMPLATE_INSTANTIATED before
	calling regenerate_decl_from_template.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.3076.2.237&r2=1.3076.2.238
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/pt.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.635.2.40&r2=1.635.2.41
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/instantiate6.C.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=NONE&r2=1.1.8.1

Comment 12 Gabriel Dos Reis 2004-01-21 03:26:47 UTC
Fixed with

  http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02046.html