c++/589: catch of derived classes dpnds from clause ordering and inheritance beeing public or private

Hugo.Mildenberger@topmail.de Hugo.Mildenberger@topmail.de
Mon Oct 2 10:06:00 GMT 2000


>Number:         589
>Category:       c++
>Synopsis:       catch of derived classes dpnds from clause ordering and inheritance beeing public or private
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Oct 02 10:06:00 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     Hugo Mildenberger
>Release:        g++ version 2.95.2
>Organization:
>Environment:
g++ --version: 2.95.2
ld  --version: GNU ld 2.9.5
compile cmd  : g++ -O0 -fexceptions -Wall test2.cc -o 
>Description:
The catched type of a previously thrown instance B inheriting froma A depends  from from the catch clause ordering, if the base class A is inherited publicly.

>How-To-Repeat:
// Title: catch of derived classes dpnds from clause ordering and inheritance 
// 
// Implements: a gcc-2.9.2 example to demonstrate a possible catch bug.
//
// Abstract: The catched type of a previously thrown instance B depends 
//           from from the catch clause ordering, if heir base class A 
//           is inherited publicly.
//
// Usage:   To switch to private inheritance mode do a -D PRIVATE_BASE_A
//
// g++ --version: 2.95.2
// ld  --version: GNU ld 2.9.5
// compile cmd  : g++ -O0 -fexceptions -Wall test2.cc -o test2
//
// Author       : Hugo.Mildenberger@topmail.de
//
// Output with publicly inherited class A: (erroneous)
//
// case 1a: throw a pointer to B, catch A*, B*
// catch(A *e): instance type is B
// ------------------------------------------
// case 1b: throw apointer to B, catch B*, A*
// catch(B *e): instance type is B
// ------------------------------------------
// case 2a: throw B by value, catch A&, B&
// catch(A &e): instance type is B
// ------------------------------------------
// case 2b: throw B by value, catch B&, A&
// catch(B &e): instance type is B
// ------------------------------------------
// case 3a: throw B by value, catch A, B
// catch(A  e): instance type is A
// ------------------------------------------
// case 3b: throw B by value, catch B,A
// catch(B  e): instance type is B
//
// *******************************************
// Output if class A is inherited privately: (is ok).
// *******************************************
// 
// case 1a: throw a pointer to B, catch A*, B*
// catch(B *e): instance type is B
// -----------------------------------------
// case 1b: throw apointer to B, catch B*, A*
// catch(B *e): instance type is B
//------------------------------------------
// case 2a: throw B by value, catch A&, B&
// catch(B &e): instance type is B
//------------------------------------------
// case 2b: throw B by value, catch B&, A&
// catch(B &e): instance type is B
// ------------------------------------------
// case 3a: throw B by value, catch A, B
// catch(B  e): instance type is B
// ------------------------------------------
// case 3b: throw B by value, catch B,A
// catch(B  e): instance type is B
//
// *******************************************

#include <iostream.h>

class A {
  public: A(){};
  virtual const char * whoami(){ return "A";};
};

#ifdef PRIVATE_BASE_A
	class B: A{
	  public: B():A(){}
	  virtual const char * whoami(){ return "B";};
	};
#else
	class B: public A{
	  public: B():A(){}
	  virtual const char * whoami(){ return "B";};
	};
#endif

int main(){
        cout << "case 1a: throw a pointer to B, catch A*, B*" << endl;
	try {
	    throw  new B;
	}
	catch(A *e){
	      cout << "catch(A *e): instance type is " << e->whoami()<<endl;
	}
	catch(B *e){
	      cout << "catch(B *e): instance type is " << e->whoami()<<endl;
	}
        cout << "------------------------------------------" << endl;
        cout << "case 1b: throw apointer to B, catch B*, A*" << endl;
	try {
	    throw  new B;
	}
	catch(B *e){
	      cout << "catch(B *e): instance type is " << e->whoami()<<endl;
	}
	catch(A *e){
	      cout << "catch(A *e): instance type is " << e->whoami()<<endl;
	}

        cout << "------------------------------------------" << endl;
        cout << "case 2a: throw B by value, catch A&, B&" << endl;
	try {
	    throw B();
	}
	catch(A &e){
	      cout << "catch(A &e): instance type is " << e.whoami()<<endl;
	}
	catch(B &e){
	      cout << "catch(B &e): instance type is " << e.whoami()<<endl;
	}
        cout << "------------------------------------------" << endl;
        cout << "case 2b: throw B by value, catch B&, A&" << endl;
	try {
	    throw B();
	}
	catch(B &e){
	      cout << "catch(B &e): instance type is " << e.whoami()<<endl;
	}
	catch(A &e){
	      cout << "catch(A &e): instance type is " << e.whoami()<<endl;
	}


        cout << "------------------------------------------" << endl;
        cout << "case 3a: throw B by value, catch A, B" << endl;
	try {
	    throw B();
	}
	catch(A e){
	     cout << "catch(A  e): instance type is " << e.whoami()<<endl;
	}
	catch(B e){
	      cout << "catch(B  e): instance type is " << e.whoami()<<endl;
	}
   
        cout << "------------------------------------------" << endl;
        cout << "case 3b: throw B by value, catch B,A" << endl;

    try {
	    throw B();
	}
	catch(B e){
	      cout << "catch(B  e): instance type is " << e.whoami()<<endl;
	}
	catch(A e){
	     cout << "catch(A  e): instance type is " << e.whoami()<<endl;
	}

}
>Fix:
not known. Changing inheritance to private make the class
potentially unusable without rewriting each method
>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="test2.c"
Content-Disposition: inline; filename="test2.c"

// Title: catch of derived classes dpnds from clause ordering and inheritance 
// 
// Implements: a gcc-2.9.2 example to demonstrate a possible catch bug.
//
// Abstract: The catched type of a previously thrown instance B depends 
//           from from the catch clause ordering, if heir base class A 
//           is inherited publicly.
//
// Usage:   To switch to private inheritance mode do a -D PRIVATE_BASE_A
//
// g++ --version: 2.95.2
// ld  --version: GNU ld 2.9.5
// compile cmd  : g++ -O0 -fexceptions -Wall test2.cc -o test2
//
// Author       : Hugo.Mildenberger@topmail.de
//
// Output with publicly inherited class A: (erroneous)
//
// case 1a: throw a pointer to B, catch A*, B*
// catch(A *e): instance type is B
// ------------------------------------------
// case 1b: throw apointer to B, catch B*, A*
// catch(B *e): instance type is B
// ------------------------------------------
// case 2a: throw B by value, catch A&, B&
// catch(A &e): instance type is B
// ------------------------------------------
// case 2b: throw B by value, catch B&, A&
// catch(B &e): instance type is B
// ------------------------------------------
// case 3a: throw B by value, catch A, B
// catch(A  e): instance type is A
// ------------------------------------------
// case 3b: throw B by value, catch B,A
// catch(B  e): instance type is B
//
// *******************************************
// Output if class A is inherited privately: (is ok).
// *******************************************
// 
// case 1a: throw a pointer to B, catch A*, B*
// catch(B *e): instance type is B
// -----------------------------------------
// case 1b: throw apointer to B, catch B*, A*
// catch(B *e): instance type is B
//------------------------------------------
// case 2a: throw B by value, catch A&, B&
// catch(B &e): instance type is B
//------------------------------------------
// case 2b: throw B by value, catch B&, A&
// catch(B &e): instance type is B
// ------------------------------------------
// case 3a: throw B by value, catch A, B
// catch(B  e): instance type is B
// ------------------------------------------
// case 3b: throw B by value, catch B,A
// catch(B  e): instance type is B
//
// *******************************************

#include <iostream.h>

class A {
  public: A(){};
  virtual const char * whoami(){ return "A";};
};

#ifdef PRIVATE_BASE_A
	class B: A{
	  public: B():A(){}
	  virtual const char * whoami(){ return "B";};
	};
#else
	class B: public A{
	  public: B():A(){}
	  virtual const char * whoami(){ return "B";};
	};
#endif

int main(){
        cout << "case 1a: throw a pointer to B, catch A*, B*" << endl;
	try {
	    throw  new B;
	}
	catch(A *e){
	      cout << "catch(A *e): instance type is " << e->whoami()<<endl;
	}
	catch(B *e){
	      cout << "catch(B *e): instance type is " << e->whoami()<<endl;
	}
        cout << "------------------------------------------" << endl;
        cout << "case 1b: throw apointer to B, catch B*, A*" << endl;
	try {
	    throw  new B;
	}
	catch(B *e){
	      cout << "catch(B *e): instance type is " << e->whoami()<<endl;
	}
	catch(A *e){
	      cout << "catch(A *e): instance type is " << e->whoami()<<endl;
	}

        cout << "------------------------------------------" << endl;
        cout << "case 2a: throw B by value, catch A&, B&" << endl;
	try {
	    throw B();
	}
	catch(A &e){
	      cout << "catch(A &e): instance type is " << e.whoami()<<endl;
	}
	catch(B &e){
	      cout << "catch(B &e): instance type is " << e.whoami()<<endl;
	}
        cout << "------------------------------------------" << endl;
        cout << "case 2b: throw B by value, catch B&, A&" << endl;
	try {
	    throw B();
	}
	catch(B &e){
	      cout << "catch(B &e): instance type is " << e.whoami()<<endl;
	}
	catch(A &e){
	      cout << "catch(A &e): instance type is " << e.whoami()<<endl;
	}


        cout << "------------------------------------------" << endl;
        cout << "case 3a: throw B by value, catch A, B" << endl;
	try {
	    throw B();
	}
	catch(A e){
	     cout << "catch(A  e): instance type is " << e.whoami()<<endl;
	}
	catch(B e){
	      cout << "catch(B  e): instance type is " << e.whoami()<<endl;
	}
   
        cout << "------------------------------------------" << endl;
        cout << "case 3b: throw B by value, catch B,A" << endl;

    try {
	    throw B();
	}
	catch(B e){
	      cout << "catch(B  e): instance type is " << e.whoami()<<endl;
	}
	catch(A e){
	     cout << "catch(A  e): instance type is " << e.whoami()<<endl;
	}

}


More information about the Gcc-bugs mailing list