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

c++/93: Re: statement expressions implement incorrect copy semantics



>Number:         93
>Category:       c++
>Synopsis:       statement expressions implement incorrect copy semantics
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          analyzed
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Thu Mar 09 02:16:01 PST 2000
>Closed-Date:
>Last-Modified:
>Originator:     Seapig6@aol.com
>Release:        2.95.2
>Organization:
>Environment:
>Description:
 Original-Message-ID: <64246316.24708bca@aol.com>
 Date: Sun, 16 May 1999 16:59:54 EDT

 [If you need to contact me, please use kosak@cs.cmu.edu ]

 I don't know if the statement expression extension is deprecated.  If not, 
 there is a problem with it under C++.  I first noticed it in code like this:

 % cat b2.cc && g++ -v && g++ b2.cc && echo done && a.out
 #include <iostream.h>
 #include <string>

 int main()
 {
   string c;
   c=({
     string d("cow");
     d;
   });
   cout <<"c is " <<c <<endl;
   return 0;
 }
 Reading specs from 
 /afs/cs.cmu.edu/project/cmcl-kosak/various-gcc/egcs-19990502/
 i386_linux3/lib/gcc-lib/i686-pc-linux-gnu/egcs-2.93.21/specs
 gcc version egcs-2.93.21 19990502 (gcc2 ss-980929 experimental)
 done
 Segmentation fault



 The above demonstrates the bug, but code like the following is easier to 
 analyze:

 #include <iostream.h>

 struct cow {
   char x[1024];

   cow()                 { Print(__PRETTY_FUNCTION__); }
   ~cow()                { Print(__PRETTY_FUNCTION__); }
   cow(const cow &other) { Print(__PRETTY_FUNCTION__); }
   cow &operator=(const cow &other) {
     Print(__PRETTY_FUNCTION__);
     cout << "other is " << &other <<endl;
     return *this;
   }
   void Print(const char *s) {
     cout << s << ", this is " <<this <<endl;
   }
 };

 int main()
 {
   cow c;
   c=({
     cow d;
     d;
   });
   return 0;
 }
 Reading specs from 
 /afs/cs.cmu.edu/project/cmcl-kosak/various-gcc/egcs-19990502/
 i386_linux3/lib/gcc-lib/i686-pc-linux-gnu/egcs-2.93.21/specs
 gcc version egcs-2.93.21 19990502 (gcc2 ss-980929 experimental)
 cow::cow(), this is 0xbffff898
 cow::cow(), this is 0xbffff498
 cow::~cow(), this is 0xbffff498
 struct cow & cow::operator =(const cow &), this is 0xbffff898
 other is 0xbffff098
 cow::~cow(), this is 0xbffff098
 cow::~cow(), this is 0xbffff898


 Notice the destruction of 0xbffff098, an object that was never constructed!!  
 Looking at the generated assembly we learn that this object is a compiler 
 temporary that was created by a bitwise copy(!!), even though both a copy 
 constructor and operator= are defined for this object.  The object was made 
 deliberately "big" so the bitwise copy code is easy to find:

 % g++ -S bug.cc && cat bug.s
 [...]
 .LCFI7:
	 call _._3cow
	 addl $16,%esp
	 leal -3072(%ebp),%edi
	 leal -2048(%ebp),%esi
	 cld
	 movl $256,%ecx
	 rep
	 movsl


 This bitwise copy should never have happened, and is no doubt the reason for 
 the segmentation fault in the "string" code example at the top of this report.

>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:

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