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]
Other format: [Raw text]

c++/6878: Multiple inheritance structure causes segfault on delete. <synopsis of the problem (one line)>



>Number:         6878
>Category:       c++
>Synopsis:       Multiple inheritance structure causes segfault on delete.
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Thu May 30 18:16:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Doug Johnson
>Release:        3.2 20020411 (experimental)
>Organization:
>Environment:
System: Linux shimmer 2.4.18 #6 Fri Mar 22 22:12:55 CST 2002 i686 unknown
Architecture: i686

	
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: ../gcc/configure --prefix=/opt/gcc --program-suffix=-cvs --enable-languages=c,c++
>Description:
	A simple 5-element multiple inheritance structure can cause the output program to segfault
	if an object of the class is deleted by means of a pointer to a specific element of the
	inheritance structure.

	The class must have two superclasses.  Each superclass must itself have a superclass.
	If a pointer to the *second* of the initial two superclasses is deleted, the program
	will segfault.  The problem goes away if that superclass is given a virtual destructor.
	
	
>How-To-Repeat:
	
	Compile the following program with the command
	
		g++ -o delete-bug delete-bug.cc -g -Wall -Werror
	
	The program will segfault on the 'delete object;' line.

	I've commented out the output statements so that the program doesn't include
	any other files.  However, they may be useful to demonstrate where the problem
	occurs after determining that the problem is in fact in this file.
	
	I've tested this process with gcc 2.95, 3.0 and the CVS version as of April 11, 2002.
	I get the same results with each versions.
	
*** begin file ***
	//#include <iostream>
	//#include <string>

	using namespace std;

	class GrandParent { 
	public:
		// Adding a virtual destructor to the grandparent on the right side 
		// fixes the problem
		//virtual ~GrandParent() {}

		// potential workaround: 
		// adding a pure virtual function to handle deleting the object fixes the problem
		virtual void deleteMe()=0;
	};

	class LeftParent: public GrandParent {
	public:
		// a virtual destructor in the left parent doesn't help
		//virtual ~LeftParent() {}
	};

	class RightParent : public GrandParent {
	public:
		// a virtual destructor on the right parent also fixes the problem
		//virtual ~RightParent() {}
	};

	class Child: public LeftParent, public RightParent {
	public:
		void deleteMe() {
			delete this;
		}
	};
																

	int main(int argc, char **argv) {
	
		// Declaring object to be a pointer to RightParent will cause a
		// segfault when it is deleted.  Declaring it a pointer to LeftParent
		// or Child produces the desired (non-segfaulting) behavior.
		RightParent *object = new Child();
		//LeftParent *object = new Child();
		//Child *object = new Child();
														
		//cout << __FILE__ << ": trying to delete object " << object << ": " << endl;
	
		// comment out the 'delete object' line and uncomment this next line
		// to try the virtual function workaround.  It works, but is clunky.
		//object->deleteMe();
	
		delete object;
	
		//cout << __FILE__ << ": success! " << endl;
																									
		return 0;
	}
*** end file ***
	
	
>Fix:
	Give the top level classes virtual destructors.
	
>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]