Bug 17483

Summary: [4.0 regression] ICE at -O3 when passing a reference.
Product: gcc Reporter: Volker Reichelt <reichelt>
Component: tree-optimizationAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: critical CC: bangerth, gcc-bugs, gerald, rth
Priority: P2 Keywords: ice-on-valid-code, monitored
Version: 4.0.0   
Target Milestone: 4.0.0   
Host: Target:
Build: Known to work: 3.4.2
Known to fail: 4.0.0 Last reconfirmed: 2004-09-14 21:54:32
Bug Depends on:    
Bug Blocks: 8361, 17478    

Description Volker Reichelt 2004-09-14 20:01:17 UTC
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.
Comment 1 Andrew Pinski 2004-09-14 21:03:09 UTC
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>
Comment 2 Andrew Pinski 2004-09-14 21:54:32 UTC
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;
Comment 3 Andrew Pinski 2004-09-14 21:56:54 UTC
*** Bug 17478 has been marked as a duplicate of this bug. ***
Comment 4 Andrew Pinski 2004-09-15 05:55:56 UTC
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();
}
Comment 5 Andrew Pinski 2004-09-15 10:12:59 UTC
*** Bug 17497 has been marked as a duplicate of this bug. ***
Comment 6 Steven Bosscher 2004-09-15 12:15:10 UTC
I cannot reproduce this on amd64 normal or amd64 -m32.
Comment 7 Wolfgang Bangerth 2004-09-15 12:50:21 UTC
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. 
Comment 8 Andrew Pinski 2004-09-15 17:55:50 UTC
That is because NRV is not happening until later for i686.
But this can be reproduced on ppc for sure.
Comment 9 Andrew Pinski 2004-09-16 01:57:06 UTC
I have a fix for this problem.  Basically we need to mark the variable as TREE_ADDRESSABLE in 
copy_body_r.
Comment 10 Andrew Pinski 2004-09-16 02:12:56 UTC
Patch here: <http://gcc.gnu.org/ml/gcc-patches/2004-09/msg01640.html>.
Comment 11 Andrew Pinski 2004-09-16 03:27:42 UTC
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 :) ).
Comment 12 Andrew Pinski 2004-09-17 01:36:00 UTC
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).
Comment 13 Andrew Pinski 2004-09-17 03:32:17 UTC
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.
Comment 14 Andrew Pinski 2004-09-18 14:40:20 UTC
Fixed by the patch which fixed 17153.