Compiling a .cpp file with the following contents triggers an internal compiler error: <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< /* * The two Traits templates here are essentially std::iterator_traits * stripped right down with just enough left to make the test-case work: */ template<typename _Type> struct Traits; template<typename _Type> struct Traits<_Type *> { typedef _Type& reference; }; /* * TraitedWrapper is essentially __gnu_cxx::__normal_iterator stripped * to the minimum required to make the test-case work: */ template<typename _Pointer> class TraitedWrapper { public: typedef typename Traits<_Pointer>::reference reference; TraitedWrapper(const _Pointer pointer) : pointer_(pointer) { } reference get() const { return *pointer_; } private: _Pointer pointer_; }; /* * SpecialWrapper is essentially a form of TraitedWrapper that is * specialised for the pointer case in the way that Traits is. */ template<typename _Type> class SpecialWrapper; template<typename _Type> class SpecialWrapper<_Type *> { public: SpecialWrapper(_Type *pointer) : pointer_(pointer) { } _Type get() const { return *pointer_; } private: _Type *pointer_; }; /* * inner() throws a copy of an object returned by reference from * a method whose return-type is sometimes deduced by some template * indirection. It's templated to show what happens with different * combinations of return-type deduction and copy-constructor origin. */ template<template<typename> class _Wrapper, typename _Type> void inner() { _Type orig; _Wrapper<_Type *> wrapper(&orig); /* * No problem copy-constructing a stack-variable from the iterator: */ _Type copy(wrapper.get()); if( true ) /* * No problem throwing the stack-variable: */ throw copy; else /* * ICE can happen here, when directly throwing a copy, * depending on template parameters: */ throw _Type(wrapper.get()); } struct Generated { }; struct Manual { Manual() { } Manual(const Manual&) { } }; void outer() { inner<SpecialWrapper, Manual>(); inner<SpecialWrapper, Generated>(); inner<TraitedWrapper, Manual>(); /* * ICE when the wrapper get-method has a traits-deduced return-type * and the class has a compiler-supplied copy-constructor: */ inner<TraitedWrapper, Generated>(); } >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Issued command-line: g++ -Wall -W -Wundef -Wpointer-arith -g -O0 -c -o /dev/null bug.cpp Resulting output: bug.cpp: In function 'void inner() [with _Wrapper = TraitedWrapper, _Type = Generated]': bug.cpp:101: instantiated from here bug.cpp:79: internal compiler error: in stabilize_call, at cp/tree.c:2248 Please submit a full bug report, ... Full output from running with "-v --save-temps" is as follows: g++ -v -save-temps -Wall -W -Wundef -Wpointer-arith -g -O0 -c -o /dev/null bug.cpp <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Using built-in specs. Target: i686-pc-linux-gnu Configured with: ../gcc-4.1.1/configure --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-languages=c,c++ Thread model: posix gcc version 4.1.1 /usr/local/libexec/gcc/i686-pc-linux-gnu/4.1.1/cc1plus -E -quiet -v -D_GNU_SOURCE bug.cpp -mtune=pentiumpro -Wall -W -Wundef -Wpointer-arith -fworking-directory -O0 -fpch-preprocess -o bug.ii ignoring nonexistent directory "NONE/include" ignoring nonexistent directory "/usr/local/lib/gcc/i686-pc-linux-gnu/4.1.1/../../../../i686-pc-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /usr/local/lib/gcc/i686-pc-linux-gnu/4.1.1/../../../../include/c++/4.1.1 /usr/local/lib/gcc/i686-pc-linux-gnu/4.1.1/../../../../include/c++/4.1.1/i686-pc-linux-gnu /usr/local/lib/gcc/i686-pc-linux-gnu/4.1.1/../../../../include/c++/4.1.1/backward /usr/local/include /usr/local/lib/gcc/i686-pc-linux-gnu/4.1.1/include /usr/include End of search list. /usr/local/libexec/gcc/i686-pc-linux-gnu/4.1.1/cc1plus -fpreprocessed bug.ii -quiet -dumpbase bug.cpp -mtune=pentiumpro -auxbase-strip /dev/null -g -O0 -Wall -W -Wundef -Wpointer-arith -version -o bug.s GNU C++ version 4.1.1 (i686-pc-linux-gnu) compiled by GNU C version 4.1.1. GGC heuristics: --param ggc-min-expand=63 --param ggc-min-heapsize=63424 Compiler executable checksum: 5c1ee95ea2451a4e1aafd30c10a207cb bug.cpp: In function 'void inner() [with _Wrapper = TraitedWrapper, _Type = Generated]': bug.cpp:101: instantiated from here bug.cpp:79: internal compiler error: in stabilize_call, at cp/tree.c:2248 Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
I have been able to reproduce the same ICE in 3.4.2, gcc version 3.4.2 20040827 (prerelease) [FreeBSD] but not in 2.95.4 or 4.1.2: gcc version 2.95.4 20020320 [FreeBSD] gcc version 4.1.2 (Ubuntu 4.1.2-0ubuntu4) I originally found the ICE in some code that was throwing a copy of an object in a std::vector on the stack. By playing around with the test code I posted, I found that it seems to trigger only when the following three conditions occur together: * the copy is directly thrown, and not when the a copy is declared on the stack and then thrown; * the method that provides the reference to be copied has a return-type deduced from a traits template; * the class of the object being thrown does not provide a copy-constructor. I've tried to illustrate in the full test case that, if any one of these conditions is false, then the ICE doesn't happen. The following shorter test-case also triggers the error. I know it includes a standard header, and I haven't provided pre-processed sources for this, but it's just for illustration purposes. <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #include <vector> /* * inner() throws a copy of an object contained in a vector. * It's templated to show what happens with different _Types. */ template<typename _Type> void inner() { typename std::vector<_Type> vector(1); throw _Type(*vector.begin()); } struct Generated { }; struct Manual { Manual() { } Manual(const Manual&) { } }; void outer() { // No problems when the class has a hand-written copy-constructor: inner<Manual>(); // ICE when the class has a compiler-supplied copy-constructor: inner<Generated>(); } >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
So the problem is already fixed in all the active branches. Thanks, anyway!
Yes, it does not happen with recent releases. I logged it because I couldn't find any hint of this problem having been seen and noted anywhere. I just wanted to let you know about it in case the problem has simply been masked by recent code changes rather than specifically fixed (not that I'm suggesting it has ;-) I just don't know). Thanks!