1// { dg-do run  }
2// Author: Alfred Miniarik <a8601248@unet.univie.ac.at>
3// test of dynamic_cast
4// runtime detecting of valid
5// downcasts within nonpublic
6// baseclasses.
7
8extern "C" void abort();
9extern "C" int printf (const char *, ...);
10
11static int errors = 0;
12
13void error(int i)
14{
15  printf("Error %i\n",i);
16  errors++;
17}
18
19// 1. downcast
20// 1.1 single inheritance case
21
22struct A {virtual ~A(){};int i;};
23struct B : A {int i;};
24struct C : B {int i;};
25struct CC : C {};
26class D : C {int i;};
27
28struct E : D {int i;};
29class F : E {int i;};
30
31void
32test01 ()
33{
34  D d;
35  if((C*)&d != dynamic_cast<C*> ((A*)&d)) error(1);
36  if((C*)&d != dynamic_cast<C*> ((B*)&d)) error(2);
37  if((B*)&d != dynamic_cast<B*> ((A*)&d)) error(3);
38
39  E e;
40  if((C*)&e != dynamic_cast<C*> ((A*)&e)) error(4);
41
42  F f;
43  if((C*)&f != dynamic_cast<C*> ((B*)&f)) error(5);
44  if((B*)&f != dynamic_cast<B*> ((A*)&f)) error(6);
45  if((E*)&f != dynamic_cast<E*> ((D*)&f)) error(7);
46  if(dynamic_cast<E*> ((C*)&f)) error(8); //counter example
47}
48
49// 1.2 multiple inheritance case
50
51struct G : CC, F{};
52
53void
54test02 ()
55{
56  G g;
57  if((B*)(F*)&g != dynamic_cast<B*> ((A*)(F*)&g)) error(9);
58  if(dynamic_cast<D*> ((A*)(F*)&g)) error(10);
59  if(dynamic_cast<G*> ((B*)(F*)&g)) error(11);
60}
61
62// 2. crosscast (always fail)
63
64struct I : C{};
65struct J : F{};
66struct K : I, J{};
67class L : K{};
68
69void
70test03 ()
71{
72  L l;
73  if(dynamic_cast<J*> ((I*)&l)) error(12);
74  if(dynamic_cast<J*> ((E*)&l)) error(13);
75  if(dynamic_cast<I*> ((J*)&l)) error(14);
76}
77
78int
79main ()
80{
81  test01();
82  test02();
83  test03();
84  return errors ? 1 : 0;
85}
86