1 | //===----------------------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | // This test requires PR33425, PR33487 and PR33439. |
10 | // XFAIL: using-built-library-before-llvm-9 |
11 | |
12 | #include <cassert> |
13 | |
14 | // This test explicitly tests dynamic cast with types that have inaccessible |
15 | // bases. |
16 | #if defined(__clang__) |
17 | # pragma clang diagnostic ignored "-Winaccessible-base" |
18 | #elif defined(__GNUC__) |
19 | # pragma GCC diagnostic ignored "-Winaccessible-base" |
20 | #endif |
21 | |
22 | typedef char Pad1[43981]; |
23 | typedef char Pad2[34981]; |
24 | typedef char Pad3[93481]; |
25 | typedef char Pad4[13489]; |
26 | typedef char Pad5[81349]; |
27 | typedef char Pad6[34819]; |
28 | typedef char Pad7[3489]; |
29 | |
30 | namespace t1 |
31 | { |
32 | |
33 | // PR33425 |
34 | struct C3 { virtual ~C3() {} Pad1 _; }; |
35 | struct C5 : protected virtual C3 { Pad2 _; }; |
36 | struct C6 : virtual C5 { Pad3 _; }; |
37 | struct C7 : virtual C3 { Pad4 _; }; |
38 | struct C9 : C6, C7 { Pad5 _; }; |
39 | |
40 | C9 c9; |
41 | C3 *c3 = &c9; |
42 | |
43 | void test() |
44 | { |
45 | assert(dynamic_cast<C3*>(c3) == static_cast<C3*>(&c9)); |
46 | assert(dynamic_cast<C5*>(c3) == static_cast<C5*>(&c9)); |
47 | assert(dynamic_cast<C6*>(c3) == static_cast<C6*>(&c9)); |
48 | assert(dynamic_cast<C7*>(c3) == static_cast<C7*>(&c9)); |
49 | assert(dynamic_cast<C9*>(c3) == static_cast<C9*>(&c9)); |
50 | } |
51 | |
52 | } // t1 |
53 | |
54 | namespace t2 |
55 | { |
56 | |
57 | // PR33425 |
58 | struct Src { virtual ~Src() {} Pad1 _; }; |
59 | struct Mask : protected virtual Src { Pad2 _; }; |
60 | struct Dest : Mask { Pad3 _; }; |
61 | struct Root : Dest, virtual Src { Pad4 _; }; |
62 | |
63 | Root root; |
64 | Src *src = &root; |
65 | |
66 | void test() |
67 | { |
68 | assert(dynamic_cast<Src*>(src) == static_cast<Src*>(&root)); |
69 | assert(dynamic_cast<Mask*>(src) == static_cast<Mask*>(&root)); |
70 | assert(dynamic_cast<Dest*>(src) == static_cast<Dest*>(&root)); |
71 | assert(dynamic_cast<Root*>(src) == static_cast<Root*>(&root)); |
72 | } |
73 | |
74 | } // t2 |
75 | |
76 | namespace t3 |
77 | { |
78 | |
79 | // PR33487 |
80 | struct Class1 { virtual ~Class1() {} Pad1 _; }; |
81 | struct Shared : virtual Class1 { Pad2 _; }; |
82 | struct Class6 : virtual Shared { Pad3 _; }; |
83 | struct Left : Class6 { Pad4 _; }; |
84 | struct Right : Class6 { Pad5 _; }; |
85 | struct Main : Left, Right { Pad6 _; }; |
86 | |
87 | Main m; |
88 | Class1 *c1 = &m; |
89 | |
90 | void test() |
91 | { |
92 | assert(dynamic_cast<Class1*>(c1) == static_cast<Class1*>(&m)); |
93 | assert(dynamic_cast<Shared*>(c1) == static_cast<Shared*>(&m)); |
94 | assert(dynamic_cast<Class6*>(c1) == 0); |
95 | assert(dynamic_cast<Left*>(c1) == static_cast<Left*>(&m)); |
96 | assert(dynamic_cast<Right*>(c1) == static_cast<Right*>(&m)); |
97 | assert(dynamic_cast<Main*>(c1) == static_cast<Main*>(&m)); |
98 | } |
99 | |
100 | } // t3 |
101 | |
102 | namespace t4 |
103 | { |
104 | |
105 | // PR33439 |
106 | struct C2 { virtual ~C2() {} Pad1 _; }; |
107 | struct C3 { virtual ~C3() {} Pad2 _; }; |
108 | struct C4 : C3 { Pad3 _; }; |
109 | struct C8 : C2, virtual C4 { Pad4 _; }; |
110 | struct C9 : C4, C8 { Pad5 _; }; |
111 | |
112 | C9 c9; |
113 | C2 *c2 = &c9; |
114 | |
115 | void test() |
116 | { |
117 | assert(dynamic_cast<C2*>(c2) == static_cast<C2*>(&c9)); |
118 | assert(dynamic_cast<C3*>(c2) == 0); |
119 | assert(dynamic_cast<C4*>(c2) == 0); |
120 | assert(dynamic_cast<C8*>(c2) == static_cast<C8*>(&c9)); |
121 | assert(dynamic_cast<C9*>(c2) == static_cast<C9*>(&c9)); |
122 | } |
123 | |
124 | } // t4 |
125 | |
126 | namespace t5 |
127 | { |
128 | |
129 | // PR33439 |
130 | struct Dummy { virtual ~Dummy() {} Pad1 _; }; |
131 | struct Src { virtual ~Src() {} Pad2 _; }; |
132 | struct Dest : Dummy { Pad3 _; }; |
133 | struct A1 : Dest { Pad4 _; }; |
134 | struct A2 : Dest { Pad5 _; }; |
135 | struct Root : Src, A1, A2 { Pad6 _; }; |
136 | |
137 | Root root; |
138 | Src *src = &root; |
139 | |
140 | void test() |
141 | { |
142 | assert(dynamic_cast<Dummy*>(src) == 0); |
143 | assert(dynamic_cast<Src*>(src) == static_cast<Src*>(&root)); |
144 | assert(dynamic_cast<Dest*>(src) == 0); |
145 | assert(dynamic_cast<A1*>(src) == static_cast<A1*>(&root)); |
146 | assert(dynamic_cast<A2*>(src) == static_cast<A2*>(&root)); |
147 | } |
148 | |
149 | } // t5 |
150 | |
151 | int main(int, char**) |
152 | { |
153 | t1::test(); |
154 | t2::test(); |
155 | t3::test(); |
156 | t4::test(); |
157 | t5::test(); |
158 | |
159 | return 0; |
160 | } |
161 | |