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