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