From: mrs@cygnus.com (Mike Stump)
Subject: Re:  Copy constructor not called
Organization: GNUs Not Usenet
Distribution: gnu
Date: Sat, 5 Sep 1992 02:32:10 GMT

This problem should not exist in the next release of gcc.

The problem is that internally gcc uses a special extra invisible
compiler generated argument as the first parameter to the copy
constructor called in$chrg when the class has a virtual base class.
The code that identifies whether or not a given method is a copy
constructor or not did not take this into account.

Here is the patch to fix this:

*** cp-decl.c.~1~	Thu Sep  3 21:21:40 1992
--- cp-decl.c	Fri Sep  4 19:19:48 1992
*************** grok_ctor_properties (ctype, decl)
*** 8897,8902 ****
--- 8897,8910 ----
    tree parmtypes = FUNCTION_ARG_CHAIN (decl);
    tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node;
  
+   if (parmtypes && TREE_CHAIN (parmtypes)
+       && TREE_CODE (TREE_VALUE (TREE_CHAIN (parmtypes))) == REFERENCE_TYPE
+       && TYPE_USES_VIRTUAL_BASECLASSES (TREE_TYPE (TREE_VALUE (TREE_CHAIN (parmtypes)))))
+     {
+       parmtypes = TREE_CHAIN (parmtypes);
+       parmtype = TREE_VALUE (parmtypes);
+     }
+ 
    if (TREE_CODE (parmtype) == REFERENCE_TYPE
        && TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == ctype)
      {


> Message-Id: <KAMBIZ.92Jul17182411@booboo.indetech.com>
> From: Kambiz Aghaiepour   <kambiz@booboo.indetech.com>
> To: bug-g++@prep.ai.mit.edu
> Cc: Kayvan Sylvan  <kayvan@satyr.rational.com>, tilman@indetech.com
> Date: Fri, 17 Jul 92 18:49 PDT

> Tim Sullivan writes:

> The copy constructor for a class that has a virtual base class
> is not called when an instance of that class is passed
> on the stack.  A bit-wise copy is performed instead.  

> The 1.39 version of the compiler produced a warning message,
> the new 2.2 version has the same bug with no warning message.

> ------------

> This happens on both a sun sparc running 4.1.1 with gcc-2.2.2 and on a
> decstaion running ultrix 4.2 also with gcc-2.2.2

> Here is a sample input file and the output follows :

> ----copy_const.cxx----
> #include <string.h>

> extern "C" {
>     void printf (...);
>     void free(void *);
>     char *malloc(size_t);
> }

> #include <malloc.h>

> class Object {
> public:
>     Object();
> };

> Object::Object()
> {
> }

>  
> class String : virtual public Object {  // do not use virtual here and things
>     char 	*p;                     // work correctly...????
>     int		len, alloc;
> public:
>     String (char *val);
>     String(const String&);
>     ~String ();
>     void print ();
> };


> String::String (char *v)
> {
>     len = strlen (v);
>     alloc = len;
>     p = strdup (v);
> }

> String::~String()
> {
>     free (p);
>     p = 0;
>     len = 0;
> }

> void String::print ()
> {
>     printf ("%x=%s\n", p, p);
> }

> String::String(const String& s)
> {
>     len = s.len;
>     alloc = len + 1;
>     p = (char*)malloc(alloc);
>     strcpy (p,s.p);
> }

> void fnc (String s1)
> {
>     s1.print();
> }

> main()
> {
>     String a ("Test string");
>     fnc (a);
>     a.print();
> }

> ---end copy_const.cxx---

> The output when base class is virtual is :

> 6140=Test string
> 6140=Test string

> But deleting the word virtual and recompiling ....

> 6158=Test string
> 6140=Test string

> Why should having a virtual base class make a difference???