With -O2 -fnon-call-exceptions, the following code causes an ICE in g++ 3.3: #include <vector> class B { public: B (const std::vector<int> &a); std::vector<int> _a; }; B::B(const std::vector<int> &a) { _a = a; } adding -fno-gcse causes the ICE to disappear. This code snippet works in gcc-3.2.3 gcc-3.0.4 and gcc-3.4 (cvs head) preprocessed source from gcc-3.3 will be attached to the PR -nick > /dept/rnd/vendor/gcc-3.3/bin/g++ -v -O2 -fnon-call-exceptions ~/gcse-non-call.C Reading specs from /dept/rnd/vendor/gcc-3.3/lib/gcc-lib/i686-pc-linux-gnu/3.3/specs Configured with: ../gcc-3.3/configure --prefix=/dept/rnd/vendor/gcc-3.3 --enable-threads --enable-languages=c,c++ Thread model: posix gcc version 3.3 /dept/rnd/vendor/gcc-3.3/lib/gcc-lib/i686-pc-linux-gnu/3.3/cc1plus -quiet -v -D__GNUC__=3 -D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=0 -D_GNU_SOURCE /home/nick/gcse-non-call.C -D__GNUG__=3 -quiet -dumpbase gcse-non-call.C -auxbase gcse-non-call -O2 -version -fnon-call-exceptions -o /usr/tmp/ccaMSo6V.s GNU C++ version 3.3 (i686-pc-linux-gnu) compiled by GNU C version 2.96 20000731 (Red Hat Linux 7.1 2.96-98). GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 ignoring nonexistent directory "/dept/rnd/vendor/gcc-3.3/i686-pc-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /dept/rnd/vendor/gcc-3.3/include/c++/3.3 /dept/rnd/vendor/gcc-3.3/include/c++/3.3/i686-pc-linux-gnu /dept/rnd/vendor/gcc-3.3/include/c++/3.3/backward /usr/local/include /dept/rnd/vendor/gcc-3.3/include /dept/rnd/vendor/gcc-3.3/lib/gcc-lib/i686-pc-linux-gnu/3.3/include /usr/include End of search list. /dept/rnd/vendor/gcc-3.3/include/c++/3.3/bits/vector.tcc: In member function ` std::vector<_Tp, _Alloc>& std::vector<_Tp, _Alloc>::operator=(const std::vector<_Tp, _Alloc>&) [with _Tp = int, _Alloc = std::allocator<int>]': /home/nick/gcse-non-call.C:3: instantiated from here /dept/rnd/vendor/gcc-3.3/include/c++/3.3/bits/vector.tcc:152: internal compiler error: in commit_one_edge_insertion, at cfgrtl.c:1438
Created attachment 4157 [details] preprocessed source which triggers the ice with gcc 3.3 (bzip2) run with: g++ -O2 -fnon-call-exceptions -c gcse-non-call.ii
What a nasty bug -- only 11000 lines in the preprocessed sources and still so hard to track down... Here's a cut-down: ------------------------------------------- extern void *memmove (void *, const void *, unsigned int) throw (); struct S { int * q; S(int * i) : q(i) { } }; struct X { int *p; void foo(S first, S last) { try { memmove(0, 0, last.q - first.q); } catch(...) { throw; } } void bar (const X& x); }; void X::bar (const X& x) { const unsigned int xlen = S(x.p).q-S(x.p).q; if (xlen > 0) foo(S(x.p).q, S(x.p).q); } ------------------------------ g/x> /home/bangerth/bin/gcc-3.3-pre/bin/c++ -c y.cc -O2 -fnon-call-exceptions y.cc: In member function `void X::bar(const X&)': y.cc:23: internal compiler error: in commit_one_edge_insertion, at cfgrtl.c: 1438 Please submit a full bug report, with preprocessed source if appropriate. This works with 3.2.3 and mainline, but ICEs as above with 3.3. W.
The regression in 11083 was introduced or exposed with this patch: 2002-06-13 Jeffrey Law <law@redhat.com> * gcse.c (delete_null_pointer_checks_1): Inform caller if any null pointer checks were eliminated. Update prototype. (delete_null_pointer_checks): Similarly. * rtl.h (delete_null_pointer_checks): Update prototype. * toplev.c (rest_of_compilation): Only run cleanup_cfg if delete_null_pointer_checks deletes one or more null pointer checks. Do not run cleanup_cfg before gcse, the CFG is accurate and optimized at that point. The regression hunt used the minimized test case from comment #2 on i686-pc-linux-gnu, compiled with -O2 -fnon-call-exceptions.
Not a specialist of the subject, but trying to fix anyway.
Subject: Bug 11083 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_3-branch Changes by: ebotcazou@gcc.gnu.org 2003-07-18 06:59:24 Modified files: gcc : ChangeLog toplev.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/g++.dg/opt: cfg1.C Log message: PR optimization/11083 * toplev.c (rest_of_compilation): Delete unreachable blocks if dead edges were purged after the addressof pass. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.16114.2.670&r2=1.16114.2.671 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/toplev.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.690.2.20&r2=1.690.2.21 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.2261.2.236&r2=1.2261.2.237 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/opt/cfg1.C.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=NONE&r2=1.1.2.1
See http://gcc.gnu.org/ml/gcc-patches/2003-07/msg00807.html