1*eb8650a7SLouis Dionne //===----------------------------------------------------------------------===//
24938d48fSEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64938d48fSEric Fiselier //
74938d48fSEric Fiselier //===----------------------------------------------------------------------===//
84938d48fSEric Fiselier 
960ba1fefSLouis Dionne // PR33425 and PR33487 are not fixed until the dylib shipped with macOS 10.15
10c360553cSLouis Dionne // XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.14
1160ba1fefSLouis Dionne 
1260ba1fefSLouis Dionne // PR33439 isn't fixed until the dylib shipped with macOS 10.14
13c360553cSLouis Dionne // XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13}}
1460ba1fefSLouis Dionne 
154938d48fSEric Fiselier #include <cassert>
164938d48fSEric Fiselier 
174938d48fSEric Fiselier // This test explicitly tests dynamic cast with types that have inaccessible
184938d48fSEric Fiselier // bases.
194938d48fSEric Fiselier #if defined(__clang__)
204938d48fSEric Fiselier #   pragma clang diagnostic ignored "-Winaccessible-base"
213a244fcfSLouis Dionne #elif defined(__GNUC__)
228d313927SLouis Dionne #   pragma GCC diagnostic ignored "-Winaccessible-base"
234938d48fSEric Fiselier #endif
244938d48fSEric Fiselier 
254938d48fSEric Fiselier typedef char Pad1[43981];
264938d48fSEric Fiselier typedef char Pad2[34981];
274938d48fSEric Fiselier typedef char Pad3[93481];
284938d48fSEric Fiselier typedef char Pad4[13489];
294938d48fSEric Fiselier typedef char Pad5[81349];
304938d48fSEric Fiselier typedef char Pad6[34819];
314938d48fSEric Fiselier typedef char Pad7[3489];
324938d48fSEric Fiselier 
334938d48fSEric Fiselier namespace t1
344938d48fSEric Fiselier {
354938d48fSEric Fiselier 
364938d48fSEric Fiselier // PR33425
~C3t1::C3374938d48fSEric Fiselier struct C3 { virtual ~C3() {} Pad1 _; };
384938d48fSEric Fiselier struct C5 : protected virtual C3 { Pad2 _; };
394938d48fSEric Fiselier struct C6 : virtual C5 { Pad3 _; };
404938d48fSEric Fiselier struct C7 : virtual C3 { Pad4 _; };
414938d48fSEric Fiselier struct C9 : C6, C7 { Pad5 _; };
424938d48fSEric Fiselier 
434938d48fSEric Fiselier C9 c9;
444938d48fSEric Fiselier C3 *c3 = &c9;
454938d48fSEric Fiselier 
test()464938d48fSEric Fiselier void test()
474938d48fSEric Fiselier {
484938d48fSEric Fiselier     assert(dynamic_cast<C3*>(c3) == static_cast<C3*>(&c9));
494938d48fSEric Fiselier     assert(dynamic_cast<C5*>(c3) == static_cast<C5*>(&c9));
504938d48fSEric Fiselier     assert(dynamic_cast<C6*>(c3) == static_cast<C6*>(&c9));
514938d48fSEric Fiselier     assert(dynamic_cast<C7*>(c3) == static_cast<C7*>(&c9));
524938d48fSEric Fiselier     assert(dynamic_cast<C9*>(c3) == static_cast<C9*>(&c9));
534938d48fSEric Fiselier }
544938d48fSEric Fiselier 
554938d48fSEric Fiselier }  // t1
564938d48fSEric Fiselier 
574938d48fSEric Fiselier namespace t2
584938d48fSEric Fiselier {
594938d48fSEric Fiselier 
604938d48fSEric Fiselier // PR33425
~Srct2::Src614938d48fSEric Fiselier struct Src { virtual ~Src() {} Pad1 _; };
624938d48fSEric Fiselier struct Mask : protected virtual Src { Pad2 _; };
634938d48fSEric Fiselier struct Dest : Mask { Pad3 _; };
644938d48fSEric Fiselier struct Root : Dest, virtual Src { Pad4 _; };
654938d48fSEric Fiselier 
664938d48fSEric Fiselier Root root;
674938d48fSEric Fiselier Src *src = &root;
684938d48fSEric Fiselier 
test()694938d48fSEric Fiselier void test()
704938d48fSEric Fiselier {
714938d48fSEric Fiselier     assert(dynamic_cast<Src*>(src) == static_cast<Src*>(&root));
724938d48fSEric Fiselier     assert(dynamic_cast<Mask*>(src) == static_cast<Mask*>(&root));
734938d48fSEric Fiselier     assert(dynamic_cast<Dest*>(src) == static_cast<Dest*>(&root));
744938d48fSEric Fiselier     assert(dynamic_cast<Root*>(src) == static_cast<Root*>(&root));
754938d48fSEric Fiselier }
764938d48fSEric Fiselier 
774938d48fSEric Fiselier }  // t2
784938d48fSEric Fiselier 
794938d48fSEric Fiselier namespace t3
804938d48fSEric Fiselier {
814938d48fSEric Fiselier 
824938d48fSEric Fiselier // PR33487
~Class1t3::Class1834938d48fSEric Fiselier struct Class1 { virtual ~Class1() {} Pad1 _; };
844938d48fSEric Fiselier struct Shared : virtual Class1 { Pad2 _; };
854938d48fSEric Fiselier struct Class6 : virtual Shared { Pad3 _; };
864938d48fSEric Fiselier struct Left : Class6 { Pad4 _; };
874938d48fSEric Fiselier struct Right : Class6 { Pad5 _; };
884938d48fSEric Fiselier struct Main : Left, Right { Pad6 _; };
894938d48fSEric Fiselier 
904938d48fSEric Fiselier Main m;
914938d48fSEric Fiselier Class1 *c1 = &m;
924938d48fSEric Fiselier 
test()934938d48fSEric Fiselier void test()
944938d48fSEric Fiselier {
954938d48fSEric Fiselier     assert(dynamic_cast<Class1*>(c1) == static_cast<Class1*>(&m));
964938d48fSEric Fiselier     assert(dynamic_cast<Shared*>(c1) == static_cast<Shared*>(&m));
974938d48fSEric Fiselier     assert(dynamic_cast<Class6*>(c1) == 0);
984938d48fSEric Fiselier     assert(dynamic_cast<Left*>(c1) == static_cast<Left*>(&m));
994938d48fSEric Fiselier     assert(dynamic_cast<Right*>(c1) == static_cast<Right*>(&m));
1004938d48fSEric Fiselier     assert(dynamic_cast<Main*>(c1) == static_cast<Main*>(&m));
1014938d48fSEric Fiselier }
1024938d48fSEric Fiselier 
1034938d48fSEric Fiselier }  // t3
1044938d48fSEric Fiselier 
10529e02657SEric Fiselier namespace t4
10629e02657SEric Fiselier {
10729e02657SEric Fiselier 
10829e02657SEric Fiselier // PR33439
~C2t4::C210929e02657SEric Fiselier struct C2 { virtual ~C2() {} Pad1 _; };
~C3t4::C311029e02657SEric Fiselier struct C3 { virtual ~C3() {} Pad2 _; };
11129e02657SEric Fiselier struct C4 : C3 { Pad3 _; };
11229e02657SEric Fiselier struct C8 : C2, virtual C4 { Pad4 _; };
11329e02657SEric Fiselier struct C9 : C4, C8 { Pad5 _; };
11429e02657SEric Fiselier 
11529e02657SEric Fiselier C9 c9;
11629e02657SEric Fiselier C2 *c2 = &c9;
11729e02657SEric Fiselier 
test()11829e02657SEric Fiselier void test()
11929e02657SEric Fiselier {
12029e02657SEric Fiselier     assert(dynamic_cast<C2*>(c2) == static_cast<C2*>(&c9));
12129e02657SEric Fiselier     assert(dynamic_cast<C3*>(c2) == 0);
12229e02657SEric Fiselier     assert(dynamic_cast<C4*>(c2) == 0);
12329e02657SEric Fiselier     assert(dynamic_cast<C8*>(c2) == static_cast<C8*>(&c9));
12429e02657SEric Fiselier     assert(dynamic_cast<C9*>(c2) == static_cast<C9*>(&c9));
12529e02657SEric Fiselier }
12629e02657SEric Fiselier 
12729e02657SEric Fiselier }  // t4
12829e02657SEric Fiselier 
12929e02657SEric Fiselier namespace t5
13029e02657SEric Fiselier {
13129e02657SEric Fiselier 
13229e02657SEric Fiselier // PR33439
~Dummyt5::Dummy13329e02657SEric Fiselier struct Dummy { virtual ~Dummy() {} Pad1 _; };
~Srct5::Src13429e02657SEric Fiselier struct Src { virtual ~Src() {} Pad2 _; };
13529e02657SEric Fiselier struct Dest : Dummy { Pad3 _; };
13629e02657SEric Fiselier struct A1 : Dest { Pad4 _; };
13729e02657SEric Fiselier struct A2 : Dest { Pad5 _; };
13829e02657SEric Fiselier struct Root : Src, A1, A2 { Pad6 _; };
13929e02657SEric Fiselier 
14029e02657SEric Fiselier Root root;
14129e02657SEric Fiselier Src *src = &root;
14229e02657SEric Fiselier 
test()14329e02657SEric Fiselier void test()
14429e02657SEric Fiselier {
14529e02657SEric Fiselier     assert(dynamic_cast<Dummy*>(src) == 0);
14629e02657SEric Fiselier     assert(dynamic_cast<Src*>(src) == static_cast<Src*>(&root));
14729e02657SEric Fiselier     assert(dynamic_cast<Dest*>(src) == 0);
14829e02657SEric Fiselier     assert(dynamic_cast<A1*>(src) == static_cast<A1*>(&root));
14929e02657SEric Fiselier     assert(dynamic_cast<A2*>(src) == static_cast<A2*>(&root));
15029e02657SEric Fiselier }
15129e02657SEric Fiselier 
15229e02657SEric Fiselier }  // t5
15329e02657SEric Fiselier 
main(int,char **)154504bc07dSLouis Dionne int main(int, char**)
1554938d48fSEric Fiselier {
1564938d48fSEric Fiselier     t1::test();
1574938d48fSEric Fiselier     t2::test();
1584938d48fSEric Fiselier     t3::test();
15929e02657SEric Fiselier     t4::test();
16029e02657SEric Fiselier     t5::test();
161504bc07dSLouis Dionne 
162504bc07dSLouis Dionne     return 0;
1634938d48fSEric Fiselier }
164