145
|
1 // PR c++/88337 - Implement P1327R1: Allow dynamic_cast/typeid in constexpr.
|
|
2 // { dg-do compile { target c++2a } }
|
|
3
|
|
4 // Adopted from g++.old-deja/g++.other/dyncast1.C.
|
|
5 // But use reference dynamic_cast.
|
|
6
|
|
7 // 1. downcast
|
|
8 // 1.1. single inheritance case
|
|
9
|
|
10 struct A { virtual void a(); };
|
|
11 struct AA : A {};
|
|
12 struct B : A {};
|
|
13 struct BB : B {};
|
|
14 class C : B {};
|
|
15 struct D : C {};
|
|
16
|
|
17 struct CC : B {};
|
|
18 class DD : CC {};
|
|
19
|
|
20 class CCC : protected B {};
|
|
21 class DDD : protected CCC {};
|
|
22
|
|
23 constexpr D d;
|
|
24 constexpr bool b01 = (dynamic_cast<D&> ((A&)d), true); // { dg-error "reference .dynamic_cast. failed" }
|
|
25 // { dg-message "static type .const A. of its operand is a non-public base class of dynamic type .D." "" { target *-*-* } .-1 }
|
|
26 constexpr bool b02 = (dynamic_cast<D&> ((B&)d), true); // { dg-error "reference .dynamic_cast. failed" }
|
|
27 // { dg-message "static type .const B. of its operand is a non-public base class of dynamic type .D." "" { target *-*-* } .-1 }
|
|
28 static_assert (&d == &dynamic_cast<const D&> ((C&)d));
|
|
29 constexpr bool b03 = (dynamic_cast<C&> ((B&)d), true); // { dg-error "reference .dynamic_cast. failed" }
|
|
30 // { dg-message "static type .const B. of its operand is a non-public base class of dynamic type .D." "" { target *-*-* } .-1 }
|
|
31
|
|
32 constexpr DD dd;
|
|
33 constexpr bool b04 = (dynamic_cast<DD&> ((A&)dd), true); // { dg-error "reference .dynamic_cast. failed" }
|
|
34 // { dg-message "static type .const A. of its operand is a non-public base class of dynamic type .DD." "" { target *-*-* } .-1 }
|
|
35 constexpr bool b05 = (dynamic_cast<DD&> ((B&)dd), true); // { dg-error "reference .dynamic_cast. failed" }
|
|
36 // { dg-message "static type .const B. of its operand is a non-public base class of dynamic type .DD." "" { target *-*-* } .-1 }
|
|
37
|
|
38 constexpr DDD ddd;
|
|
39 constexpr bool b06 = (dynamic_cast<DDD&> ((A&)ddd), true); // { dg-error "reference .dynamic_cast. failed" }
|
|
40 // { dg-message "static type .const A. of its operand is a non-public base class of dynamic type .DDD." "" { target *-*-* } .-1 }
|
|
41 constexpr bool b07 = (dynamic_cast<DDD&> ((B&)ddd), true); // { dg-error "reference .dynamic_cast. failed" }
|
|
42 // { dg-message "static type .const B. of its operand is a non-public base class of dynamic type .DDD." "" { target *-*-* } .-1 }
|
|
43 constexpr bool b08 = (dynamic_cast<CCC&> ((B&)ddd), true); // { dg-error "reference .dynamic_cast. failed" }
|
|
44 // { dg-message "static type .const B. of its operand is a non-public base class of dynamic type .DDD." "" { target *-*-* } .-1 }
|
|
45
|
|
46 // 1.2. multiple inheritance case
|
|
47 // 1.2.1. all bases are public
|
|
48
|
|
49 struct E : D, CC {};
|
|
50 struct EE : CC, D {}; //Will search in reverse order.
|
|
51
|
|
52 constexpr E e;
|
|
53 constexpr bool b09 = (dynamic_cast<E&> ((A&)(D&)e), true); // { dg-error "reference .dynamic_cast. failed" }
|
|
54 // { dg-message "static type .A. of its operand is a non-public base class of dynamic type .E." "" { target *-*-* } .-1 }
|
|
55 constexpr bool b10 = (dynamic_cast<E&> ((B&)(D&)e), true); // { dg-error "reference .dynamic_cast. failed" }
|
|
56 // { dg-message "static type .B. of its operand is a non-public base class of dynamic type .E." "" { target *-*-* } .-1 }
|
|
57 static_assert (&e == &dynamic_cast<E&> ((C&)(D&)e));
|
|
58 static_assert (&e == &dynamic_cast<E&> ((B&)(CC&)e));
|
|
59 static_assert (&(CC&)e == &dynamic_cast<CC&> ((B&)(CC&)e));
|
|
60
|
|
61 constexpr EE ee;
|
|
62 constexpr bool b11 = (dynamic_cast<EE&> ((A&)(D&)ee), true); // { dg-error "reference .dynamic_cast. failed" }
|
|
63 // { dg-message "static type .A. of its operand is a non-public base class of dynamic type .EE." "" { target *-*-* } .-1 }
|
|
64 constexpr bool b12 = (dynamic_cast<EE&> ((B&)(D&)ee), true); // { dg-error "reference .dynamic_cast. failed" }
|
|
65 // { dg-message "static type .B. of its operand is a non-public base class of dynamic type .EE." "" { target *-*-* } .-1 }
|
|
66 static_assert (&ee == &dynamic_cast<EE&> ((C&)(D&)ee));
|
|
67 static_assert (&ee == &dynamic_cast<EE&> ((B&)(CC&)ee));
|
|
68 static_assert (&(CC&)ee == &dynamic_cast<CC&> ((B&)(CC&)ee));
|
|
69
|
|
70 // 1.2.2 one or more branches are nonpublic
|
|
71
|
|
72 struct X : private BB, E {};
|
|
73 struct Y : AA, private B {};
|
|
74
|
|
75 class XX : BB, E {};
|
|
76
|
|
77 constexpr X x;
|
|
78 static_assert (&x == &dynamic_cast<X&>((B&)(CC&)(E&)x));
|
|
79
|
|
80 constexpr XX xx;
|
|
81 constexpr bool b13 = (dynamic_cast<XX&>((B&)(CC&)(E&)xx), true); // { dg-error "reference .dynamic_cast. failed" }
|
|
82 // { dg-message "static type .B. of its operand is a non-public base class of dynamic type .XX." "" { target *-*-* } .-1 }
|
|
83
|
|
84 constexpr Y y;
|
|
85 constexpr bool b14 = (dynamic_cast<Y&>((B&)y), true); // { dg-error "reference .dynamic_cast. failed" }
|
|
86 // { dg-message "static type .const B. of its operand is a non-public base class of dynamic type .Y." "" { target *-*-* } .-1 }
|
|
87 constexpr bool b15 = (dynamic_cast<Y&>((A&)(B&)y), true); // { dg-error "reference .dynamic_cast. failed" }
|
|
88 // { dg-message "static type .A. of its operand is a non-public base class of dynamic type .Y." "" { target *-*-* } .-1 }
|
|
89
|
|
90 // 2. crosscast
|
|
91
|
|
92 struct J { virtual void j(); };
|
|
93 struct K : CC, private J {};
|
|
94 class KK : J, CC{};
|
|
95
|
|
96 constexpr bool b16 = (dynamic_cast<CC&> ((B&)(D&)e), true); // { dg-error "reference .dynamic_cast. failed" }
|
|
97 // { dg-message "static type .B. of its operand is a non-public base class of dynamic type .CC." "" { target *-*-* } .-1 }
|
|
98 static_assert (&(CC&)e == &dynamic_cast<CC&> ((C&)(D&)e));
|
|
99
|
|
100 constexpr K k;
|
|
101 constexpr bool b17 = (dynamic_cast<J&> ((B&)k), true); // { dg-error "reference .dynamic_cast. failed" }
|
|
102 // { dg-message "dynamic type .K. of its operand does not have an unambiguous public base class .J." "" { target *-*-* } .-1 }
|
|
103 constexpr KK kk;
|
|
104 constexpr bool b18 = (dynamic_cast<J&> ((CC&)kk), true); // { dg-error "reference .dynamic_cast. failed" }
|
|
105 // { dg-message "static type .const CC. of its operand is a non-public base class of dynamic type .KK." "" { target *-*-* } .-1 }
|