This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: C++ PATCH: throw (T *)NULL and dynamic_cast
- To: nathan at acm dot org
- Subject: Re: C++ PATCH: throw (T *)NULL and dynamic_cast
- From: Alfred Minarik <a8601248 at unet dot univie dot ac dot at>
- Date: Wed, 16 Jun 1999 00:08:47 +0200
- CC: egcs-patches at egcs dot cygnus dot com
Nathan Sidwell wrote:
>I'm not attaching Alfred's test case, but recommend that it is made suitable
>for testsuite inclusion.
>
And here they are ...
But I have to tell a sad story: Sidwells patch still does not work
completely.
While cleaning and completing the testcases it came up.
It is Nr. 24 in first testsuite file.
maybe your solution is irritated by the public B base from CC.
The B from which the cast starts is not a public base
of the most derived object, so the cast should fail.
A
|
from-> B
|
(private) A
\ /
C B
\ /
D CC <-to should not be reachable
\ /
E
=======================================
A sidenote on my last patch submission (just in case someone
has looked at it). Well it also has
a small leak but with other cases.
replace:
void* tmp2 = _to.dcast(_sub, require_public, tmp, &_sub, subptr);
! if(tmp2)
return tmp;
by:
void* tmp2 = _to.dcast(_sub, require_public, tmp, &_sub, subptr);
! if(tmp2 && (tmp2==subptr) )
return tmp;
But you will prefer Sidwells solution.
========================================
But now for the testsuit
----------------------dynamic_cast_nonpublic_1.C
// test of dynamic_cast
// runtime detecting of nonpublic
// inheritance within a cast
// and therefor failing with result 0.
extern "C" void abort();
//extern "C" void printf(const char*, ...);
void error(int i)
{
// printf("Error %i\n",i);
abort();
}
// 1. downcast
// 1.1. single inheritance case
struct A {virtual ~A(){}};
struct B : A {};
class C : B {};
struct D : C {};
struct CC : B {};
class DD : CC {};
class CCC : protected B {};
class DDD : protected CCC {};
void
test01 ()
{
D d;
if(dynamic_cast<D*> ((A*)&d)) error(1);
if(dynamic_cast<D*> ((B*)&d)) error(2);
if(&d != dynamic_cast<D*> ((C*)&d)) error(3); //counter example
if(dynamic_cast<C*> ((B*)&d)) error(4);
DD dd;
if(dynamic_cast<DD*> ((A*)&dd)) error(5);
if(dynamic_cast<DD*> ((B*)&dd)) error(6);
DDD ddd;
if(dynamic_cast<DDD*> ((A*)&ddd)) error(7);
if(dynamic_cast<DDD*> ((B*)&ddd)) error(8);
if(dynamic_cast<CCC*> ((B*)&ddd)) error(9);
}
// 1.2. multiple inheritance case
// 1.2.1. all bases are public
struct E : D, CC {};
struct EE : CC, D {}; //Will search in reverse order.
void
test02 ()
{
E e;
if(dynamic_cast<E*> ((A*)(D*)&e)) error(10);
if(dynamic_cast<E*> ((B*)(D*)&e)) error(11);
if(&e != dynamic_cast<E*> ((C*)(D*)&e)) error(12); //counter example
if(&e != dynamic_cast<E*> ((B*)(CC*)&e)) error(13); //counter example
if((CC*)&e != dynamic_cast<CC*> ((B*)(CC*)&e)) error(14); //counter
example
EE ee;
if(dynamic_cast<EE*> ((A*)(D*)&ee)) error(15);
if(dynamic_cast<EE*> ((B*)(D*)&ee)) error(16);
if(&ee != dynamic_cast<EE*> ((C*)(D*)&ee)) error(17); //counter
example
if(&ee != dynamic_cast<EE*> ((B*)(CC*)&ee)) error(18); //counter
example
if((CC*)&ee != dynamic_cast<CC*> ((B*)(CC*)&ee)) error(19); //counter
example
}
// 1.2.2 one or more branches are nonpublic
struct X : private B, E {};
struct Y : A, private B {};
class XX : B, E {};
void
test03 ()
{
X x;
if(&x != dynamic_cast<X*>((B*)(CC*)(E*)&x)) error(20); //counter
example
XX xx;
if(dynamic_cast<XX*>((B*)(CC*)(E*)&xx)) error(21);
Y y;
if(dynamic_cast<Y*>((B*)&y)) error (22);
if(dynamic_cast<Y*>((A*)(B*)&y)) error (23);
}
// 2. crosscast
struct J {virtual ~J(){};};
struct K : CC, private J {};
class KK : J, CC{};
void
test04 ()
{
E e;
if(dynamic_cast<CC*> ((B*)(D*)&e)) error(24);
if((CC*)&e != dynamic_cast<CC*> ((C*)(D*)&e)) error(25); //counter
example
K k;
if(dynamic_cast<J*> ((B*)&k)) error(26);
KK kk;
if(dynamic_cast<J*> ((CC*)&kk)) error(27);
}
int
main ()
{
test01();
test02();
test03();
test04();
}
----------------------end of dynamic_cast_nonpublic_1.C
----------------------dynamic_cast_nonpublic_2.C
// test of dynamic_cast
// runtime detecting of valid
// downcasts within nonpublic
// baseclasses.
extern "C" void abort();
//extern "C" void printf(const char*, ...);
void error(int i)
{
// printf("Error %i\n",i);
abort();
}
// 1. downcast
// 1.1 single inheritance case
struct A {virtual ~A(){};int i;};
struct B : A {int i;};
struct C : B {int i;};
class D : C {int i;};
struct E : D {int i;};
class F : E {int i;};
void
test01 ()
{
D d;
if((C*)&d != dynamic_cast<C*> ((A*)&d)) error(1);
if((C*)&d != dynamic_cast<C*> ((B*)&d)) error(2);
if((B*)&d != dynamic_cast<B*> ((A*)&d)) error(3);
E e;
if((C*)&e != dynamic_cast<C*> ((A*)&e)) error(4);
F f;
if((C*)&f != dynamic_cast<C*> ((B*)&f)) error(5);
if((B*)&f != dynamic_cast<B*> ((A*)&f)) error(6);
if((E*)&f != dynamic_cast<E*> ((D*)&f)) error(7);
if(dynamic_cast<E*> ((C*)&f)) error(8); //counter example
}
// 1.2 multiple inheritance case
struct G : C, F{};
void
test02 ()
{
G g;
if((B*)(F*)&g != dynamic_cast<B*> ((A*)(F*)&g)) error(9);
if(dynamic_cast<D*> ((A*)(F*)&g)) error(10);
if(dynamic_cast<G*> ((B*)(F*)&g)) error(11);
}
// 2. crosscast (always fail)
struct I : C{};
struct J : F{};
struct K : I, J{};
class L : K{};
void
test03 ()
{
L l;
if(dynamic_cast<J*> ((I*)&l)) error(12);
if(dynamic_cast<J*> ((E*)&l)) error(13);
if(dynamic_cast<I*> ((J*)&l)) error(14);
}
int
main ()
{
test01();
test02();
test03();
}
----------------------end of dynamic_cast_nonpublic_2.C