This is the mail archive of the gcc-bugs@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]

A bug report


Hi!

October, 13 we've sent you a bug report (the copy is attached).
Unfortunately the letter with the report contains wrong 'From' address.
And now we inform you our correct e-mail address: pr@rpb.ru,
so send, please, your questions (if any) and responses to this address.

Best regards, 
Pavel Rousnak,
Nikolaj Logvinov,




Hi!

It seems we have found a bug in gcc under RedHat.
We have extracted a piece of code from our (big) program and created a test.

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

/*======================================================================*/
/* There are three objects: Base, Middle, Upper
 * Middle derived from Base, Upper - from Middle  
 * There is a virtual method 'check' defined in Base and
 * overriden in Middle. It is called twice from within destructor
 * of Middle and then called again by method 'close' which in turn
 * is called from the same destructor.
 * Each time the method is applied to the same object and passed the same 
 * argument 'src' (equal to 'this' of current object).
 * And we have different 'this' inside 'check' in different calls!!!!
 *
 * The test was built by the command:
 *     cc -o test test.cc
 *
 * The test was compiled by gcc 2.96 under RedHat Linux 7.0 (standard)
 * We had the same behavior with:
 * 	standard RedHat 6.1
 * 	standard RedHat 6.2
 * 	gcc 2.95 + RedHat 6.2
 * 
 * The test passed successfully under the systems listed below:
 *      gcc 2.95 + FreeBSD FreeBSD 4.0-STABLE (!!!)
 *      standard IBM AIX 4.2
 *      gcc 2.95 + IBM AIX 4.2
 */
/*======================================================================*/

/*======================================================================*/
class Base 
{
  public:
    virtual ~Base() { printf("delete Base %08x\n", this); }
    virtual int check(Base *src, int line) { return 0; }
};

/*======================================================================*/
class Middle : 
  virtual public Base
{
  public:
    ~Middle();

    virtual int check(Base *src, int line);
    void close();
};

/*======================================================================*/
class Upper : 
  virtual public Middle
{
  public:
    ~Upper();   
};

/*======================================================================*/
Middle::~Middle()
{
   printf("delete Middle %08x\n", this);
   /* Two lines below: the same method is called by twice... */ 
   check(this, __LINE__);
   /* ...but 'this->' at the front of the method causes strange 
    * value of 'this' in check()... */
   this->check(this, __LINE__);

   /* 'check' will be called from 'close' and there it fails again */ 
   close();
}

/*======================================================================*/
void Middle::close()
{
   printf("close Middle %08x\n", this);
   check(this, __LINE__);
}

/*======================================================================*/
/* Compare 'src' and 'this' (they should be equal to each other)
 * and print corresponding message
 */
int
Middle::check(Base *src, int line)
{
    Base* t = this;
    if( t != src ) {
      /* Oops: something wrong */
      printf("Check failed(this=%08x,line=%d): %08x != %08x!\n", 
	  					this, line, t, src);
      return 0;
    }
    else {
      /* Ok */
      printf("Check Ok(this=%08x,line=%d): %08x\n", this, line, t);
      return 1;
    }
}

/*======================================================================*/
Upper::~Upper()
{
    printf("delete Upper %08x\n", this);
}

/*======================================================================*/
int main(int argc, char **argv )
{
    /*
    Middle *obj = new Middle;
    printf("Middle created: Middle=%08x, Base=%08x\n",
	                                           obj, (Base *)obj);
    obj->check(obj, __LINE__);
    delete obj;
    printf("-----------------------\n");
    */

    Upper *upper = new Upper;
    printf("Upper created: Upper=%08x, Middle=%08x, Base=%08x\n",
	      upper, (Middle *)upper, (Base *)upper);
    /* here 'check' works fine */
    upper->check(upper, __LINE__);

    /* 'check' will be called by destructor of Middle. 
     * And it works wrong there :( */
    delete upper;

    return 0;
}
------------------------------------------------------------------------------

The output of the test:

Upper created: Upper=08051120, Middle=08051128, Base=08051124
Check Ok(this=08051128,line=121): 08051124
delete Upper 08051120
delete Middle 08051128
Check Ok(this=08051128,line=62): 08051124
Check failed(this=08051120,line=65): 08051128 != 08051124!
close Middle 08051128
Check failed(this=08051120,line=75): 08051128 != 08051124!
delete Base 08051124

------------------------------------------------------------------------------

Best regards, 
Pavel Rousnak,
Nikolaj Logvinov,





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