This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Exceptions in 2.7.2


Hi,

Consider the following simple example :

Parent.h
-----------------------------------------------------------------------------
#ifndef PARENT_H
#define PARENT_H

#include "Child.h"
#include "Goo.h"

class CParent
{
public:
                CParent(unsigned long ul,
                        const CGoo &goo) throw(CMyExcep);
  virtual       ~CParent();

protected:
                CParent(const CParent &);
  CParent       &operator=(const CParent &);

private:
  unsigned long ul;
  CChild        child;
};

#endif


Parent.cpp
-----------------------------------------------------------------------------
#include "Parent.h"

CParent::CParent(unsigned long ul,
                 const CGoo &goo) throw(CMyExcep) : ul(ul),
                                                    child(CGoo(),goo)
{
  // Imagine some code which might throw a CMyExcep here
}

CParent::~CParent()
{
}


Child.h
-----------------------------------------------------------------------------
#ifndef CHILD_H
#define CHILD_H

#include "Goo.h"

class CChild
{
public:
          CChild(const CGoo &temp,const CGoo &goo);
  virtual ~CChild();

protected:
          CChild(const CChild &);
  CChild  &operator=(const CChild &);

};

#endif


Child.cpp
-----------------------------------------------------------------------------
#include <stdio.h>

#include "Child.h"

CChild::CChild(const CGoo &temp,const CGoo &goo)
{
  printf("CChild::CChild\n");
  try
  {
    throw -1;
  }
  catch(int)
  {
  }
  printf("CChild::CChild done\n");
}

CChild::~CChild()
{
}


Goo.h
-----------------------------------------------------------------------------
#ifndef GOO_H
#define GOO_H

#include <exception>

class CMyExcep : public exception
{
};

class CGoo
{
public:
              CGoo();
  virtual     ~CGoo();
private:
  const CGoo  *p;
};

#endif


Goo.cpp
-----------------------------------------------------------------------------
#include <stdio.h>

#include "Goo.h"

CGoo::CGoo() : p(this)
{
  printf("CGoo::CGoo -> this=0x%08x\n",this);
}

CGoo::~CGoo()
{
  printf("CGoo::~CGoo -> this=0x%08x\n",this);
  if(p!=this)
  {
    printf("CGoo::~CGoo *** ERROR *** 'this' is corrupted !!\n");
  }
}


I'm using the 2.7.2-960126 compiler which comes with WindRiver's Tornado
environment on a 486 target. When I look at the assembly output for Parent.cpp
I see that the compiler generates code to construct the temporary CGoo object,
and keeps a pointer to this object in the ESI register. It then calls the
ctor for the CChild attribute. As you can see, CChild::CChild only throws
an exception which it catches itself as well (the exception never get's outside
the ctor). However, during the call to __sjthrow in the CChild ctor, the
ESI register gets messed up. This is not a problem for the CChild ctor itself
as it doesn't use the ESI register for itself. The problem occurrs when control
flows back to the initializer list of CParent. The compiler still assumes
that ESI contains a pointer to the temporary CGoo, and pushes it on stack
and calls the dtor for the temporary, yielding unexpected results ofcourse,
since the value that the this pointer had during construction of the temporary
CGoo object is not equal to the value it has during destruction.

What's causing this, and are there any command line options with which I
can either convince the compiler to not use the ESI register to keep the
temporary, or to keep __sjthrow from messing it up ? When I compile the lot
with optimization turned off, it all works fine, but that's only because
the compiler then stores the pointer to the temporary on stack, and then
retrieves that value again when it's time to call the dtor on the temporary.

I'd appreciate any help you can give me on this problem,

With kind regards,

Aloy Ambergen


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]