From: Lheureux@dice.ucl.ac.BE (Olivier L'Heureux)
Subject: gcc-2.3.2 bug report (copy c'tor & virt. members)
Organization: GNUs Not Usenet
Distribution: gnu
Date: Fri, 18 Dec 1992 16:32:08 GMT

			 gcc-2.3.2 bug report.
			=======================

Here is a problem I encoutered when trying to develop a safe integer
class. It is still another copy constructor problem; several copy
constructor bugs were already reported and this one is probably
another presentation of the same bug. 

The following program define a base class "BaseClass" with a virtual
function "virtMember", and a derived class "DerivedClass". Normally,
the base class members call the actual (derived) virtual members. But
if and only if the derived object has been initialized by copy, then
the base class members call erroneously the base class virtual
definition.

If the derived object is not initialized by copy, or if it is
initialized by the default copy constructor, the bug disappears.

I looked at the variables with gdb-4.7, the virtual pointer seems
different.

The system used is a Sun SPARC 2 with Solaris 1.1 (SunOS 4.1.3).
gcc-2.3.2 was configured with
        ./configure --target=sparc-sun-sunos4.1.3 --prefix=/dir/gnu

I am not completely sure it is a bug, however the Sun CC version 2.1
gives different results than gcc.

Merry Christmas and Happy New Year,
						Olivier L'Heureux


//-----------------------------------------------------------------------------

// Trying virtual functions.

#include <iostream.h>

//-----------------------------------------------------------------------------

class BaseClass {

  friend ostream& operator<< ( ostream& s, const BaseClass irv );

  int i;

public:

// Comment out the following line and the bug disappears.
  BaseClass( const BaseClass& ir ) : i(ir.i) {};
  BaseClass() : i(5) {};

  virtual int virtMember() { return( 999 ); };

  void Increm( int r );
};

//-----------------------------------------------------------------------------

void BaseClass::Increm( int r )
{
  cerr << "BaseClass::Increm --> {i=" << i
       << ", virtMember()=" << virtMember() << "}\n";
  i += r;
};

//----------------------------------------------------------------------------

ostream& operator<< ( ostream& s, const BaseClass irv )
{
    return( s << irv.i );
}

//----------------------------------------------------------------------------

class DerivedClass : public BaseClass {
public:

// Uncomment the following lines and the bug disappears.
//  DerivedClass() {};
//  DerivedClass ( const DerivedClass& ir ) : BaseClass(ir) {};
  int virtMember() { return( 30 ); };
};

//----------------------------------------------------------------------------

main ()
{
    DerivedClass a;

    cout << "a=" << a << "  a.virtMember()=" << a.virtMember() << "\n";
    a.Increm(2);
    cout << "a=" << a << "  a.virtMember()=" << a.virtMember() << "\n";

// "b" does not behave like "a" because "b" is initialized by copy.
    DerivedClass b = a;
    cout << "b=" << b << "  b.virtMember()=" << b.virtMember() << "\n";

    b.Increm(2); // Inside "Increm", "b" is seen as an "BaseClass".

    cout << "b=" << b << "  b.virtMember()=" << b.virtMember() << "\n";

}

----------------------------------------------------------------------
sibelius401> g++ -v bug.cc
Reading specs from /dir/gnu/lib/gcc-lib/sparc-sun-sunos4.1.3/2.3.2/specs
gcc version 2.3.2
 /dir/gnu/lib/gcc-lib/sparc-sun-sunos4.1.3/2.3.2/cpp -lang-c++ -v -undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__sparc -D__sun -D__unix bug.cc /usr/tmp/cca18279.i
GNU CPP version 2.3.2 (sparc)
 /dir/gnu/lib/gcc-lib/sparc-sun-sunos4.1.3/2.3.2/cc1plus /usr/tmp/cca18279.i -quiet -dumpbase bug.cc -version -o /usr/tmp/cca18279.s
GNU C++ version 2.3.2 (sparc) compiled by GNU C version 2.3.2.
 as -o /usr/tmp/cca182791.o /usr/tmp/cca18279.s
 /dir/gnu/lib/gcc-lib/sparc-sun-sunos4.1.3/2.3.2/ld -e start -dc -dp
/lib/crt0.o -L/dir/gnu/lib/gcc-lib/sparc-sun-sunos4.1.3/2.3.2 -L/dir/gnu/lib /usr/tmp/cca182791.o -lg++ -lgcc -lc -lgcc

sibelius402> a.out
a=5  a.virtMember()=30
BaseClass::Increm --> {i=5, virtMember()=30}
a=7  a.virtMember()=30
b=7  b.virtMember()=30
BaseClass::Increm --> {i=7, virtMember()=999}
b=9  b.virtMember()=30
sibelius403> 
sibelius404> diff -c bug.cc no-bug.cc 
*** bug.cc      Wed Dec 16 10:25:55 1992
--- no-bug.cc   Fri Dec 18 09:51:49 1992
***************
*** 13,19 ****
  public:
  
  // Comment out the following line and the bug disappears.
!   BaseClass( const BaseClass& ir ) : i(ir.i) {};
    BaseClass() : i(5) {};
  
    virtual int virtMember() { return( 999 ); };
--- 13,19 ----
  public:
  
  // Comment out the following line and the bug disappears.
! //  BaseClass( const BaseClass& ir ) : i(ir.i) {};
    BaseClass() : i(5) {};
  
    virtual int virtMember() { return( 999 ); };

sibelius405> g++ -v no-bug.cc
Reading specs from /dir/gnu/lib/gcc-lib/sparc-sun-sunos4.1.3/2.3.2/specs
gcc version 2.3.2
 /dir/gnu/lib/gcc-lib/sparc-sun-sunos4.1.3/2.3.2/cpp -lang-c++ -v -undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__sparc -D__sun -D__unix no-bug.cc /usr/tmp/cca18303.i
GNU CPP version 2.3.2 (sparc)
 /dir/gnu/lib/gcc-lib/sparc-sun-sunos4.1.3/2.3.2/cc1plus /usr/tmp/cca18303.i -quiet -dumpbase no-bug.cc -version -o /usr/tmp/cca18303.s
GNU C++ version 2.3.2 (sparc) compiled by GNU C version 2.3.2.
 as -o /usr/tmp/cca183031.o /usr/tmp/cca18303.s
 /dir/gnu/lib/gcc-lib/sparc-sun-sunos4.1.3/2.3.2/ld -e start -dc -dp /lib/crt0.o -L/dir/gnu/lib/gcc-lib/sparc-sun-sunos4.1.3/2.3.2 -L/dir/gnu/lib /usr/tmp/cca183031.o -lg++ -lgcc -lc -lgcc
sibelius406> 
sibelius406> a.out
a=5  a.virtMember()=30
BaseClass::Increm --> {i=5, virtMember()=30}
a=7  a.virtMember()=30
b=7  b.virtMember()=30
BaseClass::Increm --> {i=7, virtMember()=30}
b=9  b.virtMember()=30
sibelius407> 

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

Olivier L'Heureux

                    ,                          ,
Laboratoire de Microelectronique de l'Universite Catholique de Louvain

 ^
Batiment Maxwell			tf:	(+32) 10 47 25 83
Place du levant, 3			fax:	(+32) 10 47 86 67
B-1348 Louvain-La-Neuve			e-mail:	lheureux@dice.ucl.ac.be
	Belgium

Newsgroups: gnu.g++.bug