When compiling the attached code, I get an ICE: $ /usr/lib/gcc-snapshot/bin/g++ -v -Q -save-temps -c ice.cpp Using built-in specs. Target: i486-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 20080404-0ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-snapshot/README.Bugs --enable-languages=c,c++,java,fortran,objc,obj-c++,ada --prefix=/usr/lib/gcc-snapshot --enable-shared --with-system-zlib --disable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-awt=gtk --enable-gtk-cairo --disable-plugin --with-java-home=/usr/lib/gcc-snapshot/jre --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-mpfr --enable-targets=all --disable-werror --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu Thread model: posix gcc version 4.3.1 20080404 (prerelease) [gcc-4_3-branch revision 133917] (Ubuntu 20080404-0ubuntu1) COLLECT_GCC_OPTIONS='-v' '-Q' '-save-temps' '-c' '-shared-libgcc' '-mtune=generic' /usr/lib/gcc-snapshot/libexec/gcc/i486-linux-gnu/4.3.1/cc1plus -E -v -D_GNU_SOURCE ice.cpp -mtune=generic -fpch-preprocess -o ice.ii ignoring nonexistent directory "/usr/local/include/i486-linux-gnu" ignoring nonexistent directory "/usr/lib/gcc-snapshot/lib/gcc/i486-linux-gnu/4.3.1/../../../../i486-linux-gnu/include" ignoring nonexistent directory "/usr/include/i486-linux-gnu" #include "..." search starts here: #include <...> search starts here: /usr/lib/gcc-snapshot/lib/gcc/i486-linux-gnu/4.3.1/../../../../include/c++/4.3.1 /usr/lib/gcc-snapshot/lib/gcc/i486-linux-gnu/4.3.1/../../../../include/c++/4.3.1/i486-linux-gnu /usr/lib/gcc-snapshot/lib/gcc/i486-linux-gnu/4.3.1/../../../../include/c++/4.3.1/backward /usr/local/include /usr/lib/gcc-snapshot/include /usr/lib/gcc-snapshot/lib/gcc/i486-linux-gnu/4.3.1/include /usr/lib/gcc-snapshot/lib/gcc/i486-linux-gnu/4.3.1/include-fixed /usr/include End of search list. Execution times (seconds) TOTAL : 0.17 0.02 0.20 3835 kB COLLECT_GCC_OPTIONS='-v' '-Q' '-save-temps' '-c' '-shared-libgcc' '-mtune=generic' /usr/lib/gcc-snapshot/libexec/gcc/i486-linux-gnu/4.3.1/cc1plus -fpreprocessed ice.ii -dumpbase ice.cpp -mtune=generic -auxbase ice -version -o ice.s GNU C++ (Ubuntu 20080404-0ubuntu1) version 4.3.1 20080404 (prerelease) [gcc-4_3-branch revision 133917] (i486-linux-gnu) compiled by GNU C version 4.3.1 20080404 (prerelease) [gcc-4_3-branch revision 133917], GMP version 4.2.2, MPFR version 2.3.1. GGC heuristics: --param ggc-min-expand=98 --param ggc-min-heapsize=128223 options passed: -fpreprocessed ice.ii -mtune=generic options enabled: -falign-loops -fargument-alias -fauto-inc-dec -fbranch-count-reg -fcommon -fearly-inlining -feliminate-unused-debug-types -fexceptions -ffunction-cse -fgcse-lm -fident -fivopts -fkeep-static-consts -fleading-underscore -fmath-errno -fmerge-debug-strings -fmove-loop-invariants -fpcc-struct-return -fpeephole -fsched-interblock -fsched-spec -fsched-stalled-insns-dep -fsigned-zeros -fsplit-ivs-in-unroller -ftoplevel-reorder -ftrapping-math -ftree-cselim -ftree-loop-im -ftree-loop-ivcanon -ftree-loop-optimize -ftree-parallelize-loops= -ftree-reassoc -ftree-scev-cprop -ftree-vect-loop-version -fvar-tracking -fvect-cost-model -fzero-initialized-in-bss -m32 -m80387 -m96bit-long-double -maccumulate-outgoing-args -malign-stringops -mfancy-math-387 -mfp-ret-in-387 -mfused-madd -mglibc -mieee-fp -mno-red-zone -mno-sse4 -mpush-args -msahf -mtls-direct-seg-refs Compiler executable checksum: dd9fb97039947d8c4927d069b05a68b5 bool std::rel_ops::operator!=(const _Tp&, const _Tp&) bool std::rel_ops::operator>(const _Tp&, const _Tp&) bool std::rel_ops::operator<=(const _Tp&, const _Tp&) bool std::rel_ops::operator>=(const _Tp&, const _Tp&) void std::swap(_Tp&, _Tp&) std::pair<_T1, _T2>::pair() std::pair<_T1, _T2>::pair(const _T1&, const _T2&) std::pair<_T1, _T2>::pair(const std::pair<_U1, _U2>&) bool std::operator==(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&) bool std::operator<(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&) bool std::operator!=(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&) bool std::operator>(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&) bool std::operator<=(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&) bool std::operator>=(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&) std::pair<_T1, _T2> std::make_pair(_T1, _T2) long int std::abs(long int) ldiv_t std::div(long int, long int) long long int __gnu_cxx::abs(long long int) lldiv_t __gnu_cxx::div(long long int, long long int) mpl_::int_<N>::operator int() const mpl_::bool_<C_>::operator bool() const mpl_::integral_c<T, N>::operator T() const mpl_::integral_c<bool, C>::operator bool() const mpl_::size_t<N>::operator size_t() const boost::aligned_storage<size_, alignment_>::aligned_storage() boost::aligned_storage<size_, alignment_>::~aligned_storage() void* boost::aligned_storage<size_, alignment_>::address() const void* boost::aligned_storage<size_, alignment_>::address() const void func1(int&) func1(int&)::_scope_exit_9::_scope_exit_9(int&) func1(int&)::_scope_exit_9::_scope_exit_9(int&) func1(int&)::_scope_exit_9::_scope_exit_9(int&) func1(int&)::_scope_exit_9::~_scope_exit_9() func1(int&)::_scope_exit_9::~_scope_exit_9() func1(int&)::_scope_exit_9::~_scope_exit_9() void func2(T&) func2(T&)::_scope_exit_17::_scope_exit_17(typename __typeof__ (boost::type_of::ensure_obj(scope_exit::wrap_type(t)))::type&) func2(T&)::_scope_exit_17::~_scope_exit_17() int main() void func2(T&) [with T = double] ice.cpp: In constructor 'func2(T&)::_scope_exit_17::_scope_exit_17(typename __typeof__ (boost::type_of::ensure_obj(scope_exit::wrap_type(t)))::type&) [with T = double]': ice.cpp:15: instantiated from 'void func2(T&) [with T = double]' ice.cpp:29: instantiated from here ice.cpp:15: internal compiler error: in tsubst_copy, at cp/pt.c:9723 The same code, but used within a non-template function (func1 in the attached file) and therefore without the typename keyword, does not cause an ICE. This also happens with the other versions of gcc on my machine: $ gcc -v Using built-in specs. Target: i486-linux-gnu Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.2 --program-suffix=-4.2 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-targets=all --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu Thread model: posix gcc version 4.2.4 (Ubuntu 4.2.4-1ubuntu3) $ gcc-4.1 -v Using built-in specs. Target: i486-linux-gnu Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.1.3 --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-checking=release i486-linux-gnu Thread model: posix gcc version 4.1.3 20080308 (prerelease) (Ubuntu 4.1.2-21ubuntu1)
Created attachment 16552 [details] preprocessed source file that triggers the ICE
Reducing ...
Reduced testcase: template<typename T> T& ensure_obj(const T&); template <typename T> void func2(T& t) { typedef __typeof__(ensure_obj(t)) ttt; struct ttt1 { ttt1( ttt arg0 ){} } tttt ( t ); } main() { double d = 5; func2(d); } ---- CUT ---- If I use decltype (which is part of the C++0x standard), it works ....
3.3 did not ICE but did give the wrong error message: t.cc: In instantiation of `func2(T&) [with T = double]::ttt1': t.cc:10: instantiated from `void func2(T&) [with T = double]' t.cc:15: instantiated from here t.cc:8: error: `t' was not declared in this scope t.cc: In function `void func2(T&) [with T = double]': t.cc:15: instantiated from here t.cc:10: error: no matching function for call to `func2(T&) [with T = double]::ttt1::ttt1(double&)' t.cc:9: error: candidates are: func2(T&) [with T = double]::ttt1::ttt1(const func2(T&) [with T = double]::ttt1&) There is no use of t really at line 8 of my reduced testcase, only the use of the typedef.
I just ran into this bug too. Before I found this bug report, I did some more investigation to characterize the bug a little more. I am including my version of the reduced test case, with more commentary inline. -- // Cause: Use of __typeof__ on a templated type (dependent upon template arguments of outer function/class) as the type of an argument for any function in a locally defined class crashes g++. Since this successfully typechecks, I suspect that during symbol lookup in some IR generating phase, for arguments to a function of a local class, if a __typeof__ is involved, g++ does not properly lookup symbols in the outer function/class symbol table. template<typename ImplList> struct VertexData; template<typename LM> void init() { // Making non-templated function eliminates ICE. (Also ICEs for non-templated member function in a templated class.) VertexData<LM>* v0; // Making this non-template eliminates ICE. Changing LM to int eliminates ICE. typedef __typeof__(v0) v0_type_; // Using VertexData<LM> instead of __typeof__(v0) eliminates ICE. Using __decltype(v0) still causes ICE in GCC 4.3.4, but eliminates ICE in GCC 4.4 struct MeshConditionalInit { // Removing body of struct eliminates ICE. MeshConditionalInit(v0_type_& v0) { } // Removing argument eliminates ICE. Using v0_type_ only in body and not as argument eliminates ICE. }; // ICE still occurs when used as function argument instead of constructor argument. MeshConditionalInit bar138(v0); } int main(int argn, char ** argv) { init<int>(); } -- ICE occurs with no special compile flags in the following standard distribution packages of GCC: 4.1.3, 4.2.4, and 4.3.3 on Ubuntu 9.04 4.0.1 and 4.2.1 on Mac OS X 10.5 (the versions with XCode) 4.4.0 on Mac OS X 10.5 (MacPorts build) And because I got bored, here's a 140-character twitterable version of an even smaller test case (inlines the typeof into the constructor's argument, removing the typedef, which may not be legal, but definitely still causes an ICE in GCC): -- /*GCC Instacrash*/ template<class T> class C;template<class U> void f() {C<U>* i;struct S{S(__typeof__(i)& i){}}s(i);}int main(){f<int>();}
Fixed for 4.5.