Compiling the following valid code snippet (inspired by PR6189) on mainline with -O3 yields an ICE: =================================== struct A { int i; int& ref() { return i; } }; A foo() { A a; a.ref()=0; return a; } void bar() { foo(); } =================================== bug.cc: In function `void bar()': bug.cc:15: error: address taken, but ADDRESSABLE bit not set D.1590 bug.cc:15: internal compiler error: verify_stmts failed. Please submit a full bug report, [etc.] The regression was introduced 2004-09-13 or 2004-09-14.
Hmm, it works for me on Reading specs from /export/gates/pinskia/openbsd/bin/../lib/gcc/i686-unknown-openbsd3.1/4.0.0/ specs Configured with: /home/gates/pinskia/src/gnu/gcc/src/configure --target=i686-unknown- openbsd3.1 --host=i686-unknown-openbsd3.1 --build=i686-unknown-openbsd3.1 --disable-nls -- verbose --enable-cpp --prefix=/home/gates/pinskia/openbsd --enable-shared --disable-libmudflap --enable-languages=c,c++,objc Thread model: single gcc version 4.0.0 20040914 (experimental) Which has the following changelog entry at the top of the list: 2004-09-13 James E Wilson <wilson@specifixinc.com>
Confirmed, why I don't see in that compiler is beyond me but I see it on a different machine. This is an inlining bug. int & D.1602; struct A a; int & D.1599; struct A D.1586; # BLOCK 0 # PRED: ENTRY (fallthru) D.1602 = &D.1586.i; D.1599 = D.1602; *D.1599 = 0;
*** Bug 17478 has been marked as a duplicate of this bug. ***
Here is another example, and it does not happen in the C front-end because NRV happens later: struct A { int i; }; struct A foo() { struct A a; int *aaa = &a.i; *aaa = 0; return a; } void bar() { foo(); }
*** Bug 17497 has been marked as a duplicate of this bug. ***
I cannot reproduce this on amd64 normal or amd64 -m32.
As has been mentioned somewhere else already: the call to error() should be changed to internal_error() -- the message gcc prints looks just like a message indicating an error in the code, not one inside gcc. W.
That is because NRV is not happening until later for i686. But this can be reproduced on ppc for sure.
I have a fix for this problem. Basically we need to mark the variable as TREE_ADDRESSABLE in copy_body_r.
Patch here: <http://gcc.gnu.org/ml/gcc-patches/2004-09/msg01640.html>.
The problem comes from the tree optimizations happen for foo so the TREE_ADDRESSABLE bit is unset but since we don't do inlining from that trees we get the orginal code where we take the address. So this is really a tree problem where we don't reset the addressable flags after doing the optimizations on the tree. If we did the inlining from the optimizated code, we would not have this problem in fact we don't have to do the optimizations twice on the code (which can reduce the compile time :) ).
Here is a testcase which fails on x86 (where we do NRV early in the front-end): struct A { int i; int j, k,l,m; }; struct A foo() { struct A a; int *aaa = &a.i; *aaa = 0; return a; } void bar() { foo(); } : Search converges between 2004-08-30-trunk (#529) and 2004-08-31-trunk (#530).
I should note that the date I quoted is when &a->b (and &a.b) is no longer lowered so this was a latent bug.
Fixed by the patch which fixed 17153.