The following simple testcase

struct Foo { ~Foo() {} int i; };
struct NonPod { Foo foo[2]; };
void foo(void)
{
        NonPod x;
}

produces(!) at -O2

_Z3foov:
.LFB5:
        pushl   %ebp
.LCFI0:
        movl    %esp, %ebp
.LCFI1:
        subl    $16, %esp
.LCFI2:
        leal    -2(%ebp), %edx
        movl    %ebp, %eax
        .p2align 4,,15
.L4:
        decl    %eax
        cmpl    %edx, %eax
        jne     .L4
        leave
        ret

yay!  Looking at the optimized tree-dump, it contains a funny loop:

void foo() ()
{
  struct Foo * const this;
  register struct Foo * D.1621;
  struct Foo[2] * D.1620;
  struct NonPod x;

<bb 0>:
  if (&x.foo[2] == &x.foo) goto <L6>; else goto <L14>;

<L14>:;
  this = &x.foo[2];

<L2>:;
  this = this - 1;
  if (this == &x.foo) goto <L6>; else goto <L2>;

<L6>:;
  return;

}

which is roughly what is generated initially by the C++ frontend
for the dtor:

;; Function NonPod::~NonPod() (_ZN6NonPodD1Ev *INTERNAL* )
;; enabled by -tree-original

{
  <<< Unknown tree: if_stmt  
  1

   >>>
;
  try
    {

    }
  finally
    {
      {
        register struct Foo * D.1599;

        (if (&((struct NonPod *) this)->foo != 0B)
          {
            (void) (D.1599 = &((struct NonPod *) this)->foo + 2);
            while (1)
              {
                if (&((struct NonPod *) this)->foo == D.1599) break;
                (void) (D.1599 = D.1599 - 1);;
                __comp_dtor  (NON_LVALUE_EXPR <D.1599>);;
              };
          }
        else
          {
            0
          });
      }
    }
}
<D1598>:;

Note the same happens for empty struct Foo, but even avoiding
the ambiguous(?) &this->foo[2] - &this->foo[1] doesn't help.

The RTL unroller, if enabled, gets rid of the most ugly stuff from above,
but appearantly the tree loop optimizer does not know how to handle this
loop.

_Z3foov:
.LFB5:
        pushl   %ebp
.LCFI0:
        movl    %esp, %ebp
.LCFI1:
        subl    $16, %esp
.LCFI2:
        movl    %ebp, %esp
        popl    %ebp
        ret

-- 
           Summary: Funny (horrible) code for empty destructor
           Product: gcc
           Version: 4.0.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: tree-optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: rguenth at tat dot physik dot uni-tuebingen dot de
                CC: gcc-bugs at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19639

Reply via email to