When attached code is compiled with "g++ -01 -x c++ main.i" the result executes file. When compiled with -O2 it segfaults with "pure virtual function call". This may be a case of an overeager optimization.
Created attachment 17501 [details] tarred, gzipped preprocessed c++ source file
Additional information: adding "__attribute__((noinline))" to the constructor for xpression_adaptor (line 82452) makes the problem go away. Definitely looks like an optimization problem to me.
What target are you compiling on? I could not link this on i686-darwin: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) std::basic_string<char, std::char_traits<char>, std::allocator<char> >::reserve(unsigned int) ___assert_fail Can you give the output of gcc -v ?
I'm sorry to say that I no longer have access to the Linux machine on which I gcc-4.3 installed. I have only my windows laptop now, and I can't for the life of me get gcc-4.3 working under cygwin. I can, however, refer you to the original bug report, filed against a library in Boost: https://svn.boost.org/trac/boost/ticket/2655 For reference, here is the source code (requires Boost to be in the path, but uses the header-only parts of Boost and so does not require you to build or link to any part of Boost). {{{ #include <string> #include <boost/xpressive/xpressive_static.hpp> using std::string; namespace xpr = boost::xpressive; int main() { string text = "at"; xpr::sregex r1 = xpr::as_xpr('a'); xpr::sregex r2 = 'b' >> r1; xpr::sregex r3 = r2 | r1; xpr::regex_replace(text, r3, string("")); return 0; } }}}
I can reproduce this on x86_64-unknown-linux-gnu at -O2 with 4.3.2 and 4.5-20090402 snapshot, and at -O3 with 4.2.2 I can't reproduce it with 4.1.2
I was using Boost 1.37.0 with: Using built-in specs. Target: x86_64-unknown-linux-gnu Configured with: ../gcc-4.5-20090402/configure --prefix=/dev/shm/wakelyjo/insroot/4.5-20090402 --enable-languages=c,c++ --disable-bootstrap --disable-checking --with-gmp=/dev/shm/wakelyjo/stage --with-mpfr=/dev/shm/wakelyjo/stage Thread model: posix gcc version 4.5.0 20090402 (experimental) (GCC) and Using built-in specs. Target: i686-pc-linux-gnu Configured with: ../gcc-4.3.2/configure --prefix=/opt/gcc/32-bit/4.3.2 --enable-languages=c,c++,fortran,objc,obj-c++ --with-gnu-as --with-as=/opt/binutils/32-bit/2.18/bin/as --with-gnu-ld --with-ld=/opt/binutils/32-bit/2.18/bin/ld --with-gmp=/var/tmp/stage --with-mpfr=/var/tmp/stage --build=i686-pc-linux-gnu --with-arch=pentium4 --enable-shared --enable-threads=posix --enable-nls --enable-libstdcxx-debug --enable-__cxa_atexit Thread model: posix gcc version 4.3.2 (GCC)
Created attachment 17852 [details] unincluded testcase
4.1 and 4.2 cannot compile the testcase.
The testcase will have included lots of code from Boost headers conditionally based on __GNUC__ etc. so it's not surprising it doesn't compile with 4.1 or 4.2 If wanted I can produce an unincluded version using 4.1 and 4.2, but I assume there's no point as those branches are closed.
Subject: Re: bad optimization(?) pure virtual function call with -O2 On Mon, 11 May 2009, jwakely dot gcc at gmail dot com wrote: > ------- Comment #9 from jwakely dot gcc at gmail dot com 2009-05-11 12:42 ------- > The testcase will have included lots of code from Boost headers conditionally > based on __GNUC__ etc. so it's not surprising it doesn't compile with 4.1 or > 4.2 > > If wanted I can produce an unincluded version using 4.1 and 4.2, but I assume > there's no point as those branches are closed. Right. I was trying to check if this is a regression or not. Richard.
It does seem to be a regression. I preprocessed the program in comment 4 with GCC version 4.1.2 20071124 (Red Hat 4.1.2-42), then ran uninclude to produce a standalone testcase and compiled it with different versions of GCC GCC 4.1.1 (FSF) at -O3 doesn't call the pure virtual. GCC 4.1.2 (Red Hat) at -O3 doesn't call the pure virtual. GCC 4.2.2 (FSF) at -O3 calls the pure virtual. GCC 4.3.2 (FSF) can't compile the program (again, due to Boost's heavy use of preprocessor checks) Do you want that unincluded testcase attached?
Subject: Re: bad optimization(?) pure virtual function call with -O2 On Mon, 11 May 2009, jwakely dot gcc at gmail dot com wrote: > ------- Comment #11 from jwakely dot gcc at gmail dot com 2009-05-11 13:09 ------- > It does seem to be a regression. I preprocessed the program in comment 4 with > GCC version 4.1.2 20071124 (Red Hat 4.1.2-42), then ran uninclude to produce a > standalone testcase and compiled it with different versions of GCC > > GCC 4.1.1 (FSF) at -O3 doesn't call the pure virtual. > GCC 4.1.2 (Red Hat) at -O3 doesn't call the pure virtual. > GCC 4.2.2 (FSF) at -O3 calls the pure virtual. > GCC 4.3.2 (FSF) can't compile the program (again, due to Boost's heavy use of > preprocessor checks) > > Do you want that unincluded testcase attached? No, that's enough info. Richard.
In 4.4.0/x86_64-linux at -O2 at least the problem seems to be that in: _ZNK5boost9xpressive6detail17xpression_adaptorINS1_16static_xpressionINS1_17alternate_matcherINS1_15alternates_listINS3_INS1_13regex_matcherIN9__gnu_cxx17__normal_iteratorIPKcSsEEEENS3_INS1_21alternate_end_matcherENS1_7no_nextEEEEENS5_ISG_NS_6fusion3nilEEEEENS0_16cpp_regex_traitsIcEEEENS3_INS1_11end_matcherESE_EEEENS1_12matchable_exISB_EEE5matchERNS1_11match_stateISB_EE adaptor is destructed before the push_context_match call. In *.optimized dump we have: <bb 9>: adaptor.D.166953._vptr.matchable = &_ZTVN5boost9xpressive6detail17xpression_adaptorINS_17reference_wrapperIKNS1_17stacked_xpressionINS1 _16static_xpressionINS1_11end_matcherENS1_7no_nextEEENS5_INS1_21alternate_end_matcherES7_EEEEEENS1_9matchableIN9__gnu_cxx17__normal_itera torIPKcSsEEEEEE[2]; adaptor.xpr_.t_ = (const struct stacked_xpression *) (const struct stacked_xpression &) &this->xpr_.D.142582.alternates_.D.142415.cdr.D .142229.car.next_; adaptor.D.166953._vptr.matchable = &_ZTVN5boost9xpressive6detail9matchableIN9__gnu_cxx17__normal_iteratorIPKcSsEEEE[2]; D.187198 = push_context_match (&this->xpr_.D.142582.alternates_.D.142415.cdr.D.142229.car.D.142156.impl_, state, &adaptor.D.166953); goto <bb 11>;
In *.pre it still looks correct: adaptor.D.166953._vptr.matchable = &_ZTVN5boost9xpressive6detail17xpression_adaptorINS_17reference_wrapperIKNS1_17stacked_xpressionINS1 _16static_xpressionINS1_11end_matcherENS1_7no_nextEEENS5_INS1_21alternate_end_matcherES7_EEEEEENS1_9matchableIN9__gnu_cxx17__normal_itera torIPKcSsEEEEEE[2]; adaptor.xpr_.t_ = D.187226_39; D.187223_40 = &this_1(D)->xpr_.D.142582.alternates_.D.142415.cdr.D.142229.car.D.142156.impl_; D.187198_41 = push_context_match (D.187223_40, state_4(D), &adaptor.D.166953); and adaptor.D.166953._vptr.matchable = &_ZTVN5boost9xpressive6detail17xpression_adaptorINS_17reference_wrapperIKNS1_17stacked_xpressionINS1 _16static_xpressionINS1_11end_matcherENS1_7no_nextEEENS5_INS1_21alternate_end_matcherES7_EEEEEENS1_9matchableIN9__gnu_cxx17__normal_itera torIPKcSsEEEEEE[2]; adaptor.xpr_.t_ = D.187218_33; D.187221_34 = &this_1(D)->xpr_.D.142582.alternates_.D.142415.car.D.142156.impl_; D.187216_35 = push_context_match (D.187221_34, state_4(D), &adaptor.D.166953); but *.sink already breaks the first push_context_match call: D.187227_38 = &this_1(D)->xpr_.D.142582.alternates_.D.142415.cdr.D.142229.car.next_; D.187226_39 = (const struct stacked_xpression &) D.187227_38; adaptor.D.166953._vptr.matchable = &_ZTVN5boost9xpressive6detail17xpression_adaptorINS_17reference_wrapperIKNS1_17stacked_xpressionINS1 _16static_xpressionINS1_11end_matcherENS1_7no_nextEEENS5_INS1_21alternate_end_matcherES7_EEEEEENS1_9matchableIN9__gnu_cxx17__normal_itera torIPKcSsEEEEEE[2]; adaptor.xpr_.t_ = D.187226_39; D.187223_40 = &this_1(D)->xpr_.D.142582.alternates_.D.142415.cdr.D.142229.car.D.142156.impl_; adaptor.D.166953._vptr.matchable = &_ZTVN5boost9xpressive6detail9matchableIN9__gnu_cxx17__normal_iteratorIPKcSsEEEE[2]; D.187198_41 = push_context_match (D.187223_40, state_4(D), &adaptor.D.166953);
Ah, there are two different adaptor variables after inlining, so this might as well be a dup of PR39604.
Which means it should work with -fno-tree-sink.
GCC 4.3.4 is being released, adjusting target milestone.
*** Bug 42394 has been marked as a duplicate of this bug. ***
PR42394 has a smaller testcase (but it doesn't fail with trunk). It works with -fno-tree-sink.
*** Bug 39604 has been marked as a duplicate of this bug. ***
GCC 4.3.5 is being released, adjusting target milestone.
4.3 branch is being closed, moving to 4.4.7 target.
I think this has been fixed on the trunk by: 2011-11-08 Michael Matz <matz@suse.de> ... * tree.h (TREE_CLOBBER_P): New macro. ...
Works with 4.5 and 4.6 because tree-ssa-sink.c is basically "broken" for memory there (after alias improvements merge). That was fixed for 4.7 which was in turn broken again for this testcase which indeed was fixed by Michas patch. Thus, a 4.4. regression only now.
"Fixed" by dumber sinking in 4.5/4.6 and fixed for real in 4.7+. 4.4 is no longer supported.