1eb8650a7SLouis 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
9*34975009SLouis Dionne // This test requires PR33425, PR33487 and PR33439.
10*34975009SLouis Dionne // XFAIL: using-built-library-before-llvm-9
1160ba1fefSLouis Dionne
124938d48fSEric Fiselier #include <cassert>
134938d48fSEric Fiselier
144938d48fSEric Fiselier // This test explicitly tests dynamic cast with types that have inaccessible
154938d48fSEric Fiselier // bases.
164938d48fSEric Fiselier #if defined(__clang__)
174938d48fSEric Fiselier # pragma clang diagnostic ignored "-Winaccessible-base"
183a244fcfSLouis Dionne #elif defined(__GNUC__)
198d313927SLouis Dionne # pragma GCC diagnostic ignored "-Winaccessible-base"
204938d48fSEric Fiselier #endif
214938d48fSEric Fiselier
224938d48fSEric Fiselier typedef char Pad1[43981];
234938d48fSEric Fiselier typedef char Pad2[34981];
244938d48fSEric Fiselier typedef char Pad3[93481];
254938d48fSEric Fiselier typedef char Pad4[13489];
264938d48fSEric Fiselier typedef char Pad5[81349];
274938d48fSEric Fiselier typedef char Pad6[34819];
284938d48fSEric Fiselier typedef char Pad7[3489];
294938d48fSEric Fiselier
304938d48fSEric Fiselier namespace t1
314938d48fSEric Fiselier {
324938d48fSEric Fiselier
334938d48fSEric Fiselier // PR33425
~C3t1::C3344938d48fSEric Fiselier struct C3 { virtual ~C3() {} Pad1 _; };
354938d48fSEric Fiselier struct C5 : protected virtual C3 { Pad2 _; };
364938d48fSEric Fiselier struct C6 : virtual C5 { Pad3 _; };
374938d48fSEric Fiselier struct C7 : virtual C3 { Pad4 _; };
384938d48fSEric Fiselier struct C9 : C6, C7 { Pad5 _; };
394938d48fSEric Fiselier
404938d48fSEric Fiselier C9 c9;
414938d48fSEric Fiselier C3 *c3 = &c9;
424938d48fSEric Fiselier
test()434938d48fSEric Fiselier void test()
444938d48fSEric Fiselier {
454938d48fSEric Fiselier assert(dynamic_cast<C3*>(c3) == static_cast<C3*>(&c9));
464938d48fSEric Fiselier assert(dynamic_cast<C5*>(c3) == static_cast<C5*>(&c9));
474938d48fSEric Fiselier assert(dynamic_cast<C6*>(c3) == static_cast<C6*>(&c9));
484938d48fSEric Fiselier assert(dynamic_cast<C7*>(c3) == static_cast<C7*>(&c9));
494938d48fSEric Fiselier assert(dynamic_cast<C9*>(c3) == static_cast<C9*>(&c9));
504938d48fSEric Fiselier }
514938d48fSEric Fiselier
524938d48fSEric Fiselier } // t1
534938d48fSEric Fiselier
544938d48fSEric Fiselier namespace t2
554938d48fSEric Fiselier {
564938d48fSEric Fiselier
574938d48fSEric Fiselier // PR33425
~Srct2::Src584938d48fSEric Fiselier struct Src { virtual ~Src() {} Pad1 _; };
594938d48fSEric Fiselier struct Mask : protected virtual Src { Pad2 _; };
604938d48fSEric Fiselier struct Dest : Mask { Pad3 _; };
614938d48fSEric Fiselier struct Root : Dest, virtual Src { Pad4 _; };
624938d48fSEric Fiselier
634938d48fSEric Fiselier Root root;
644938d48fSEric Fiselier Src *src = &root;
654938d48fSEric Fiselier
test()664938d48fSEric Fiselier void test()
674938d48fSEric Fiselier {
684938d48fSEric Fiselier assert(dynamic_cast<Src*>(src) == static_cast<Src*>(&root));
694938d48fSEric Fiselier assert(dynamic_cast<Mask*>(src) == static_cast<Mask*>(&root));
704938d48fSEric Fiselier assert(dynamic_cast<Dest*>(src) == static_cast<Dest*>(&root));
714938d48fSEric Fiselier assert(dynamic_cast<Root*>(src) == static_cast<Root*>(&root));
724938d48fSEric Fiselier }
734938d48fSEric Fiselier
744938d48fSEric Fiselier } // t2
754938d48fSEric Fiselier
764938d48fSEric Fiselier namespace t3
774938d48fSEric Fiselier {
784938d48fSEric Fiselier
794938d48fSEric Fiselier // PR33487
~Class1t3::Class1804938d48fSEric Fiselier struct Class1 { virtual ~Class1() {} Pad1 _; };
814938d48fSEric Fiselier struct Shared : virtual Class1 { Pad2 _; };
824938d48fSEric Fiselier struct Class6 : virtual Shared { Pad3 _; };
834938d48fSEric Fiselier struct Left : Class6 { Pad4 _; };
844938d48fSEric Fiselier struct Right : Class6 { Pad5 _; };
854938d48fSEric Fiselier struct Main : Left, Right { Pad6 _; };
864938d48fSEric Fiselier
874938d48fSEric Fiselier Main m;
884938d48fSEric Fiselier Class1 *c1 = &m;
894938d48fSEric Fiselier
test()904938d48fSEric Fiselier void test()
914938d48fSEric Fiselier {
924938d48fSEric Fiselier assert(dynamic_cast<Class1*>(c1) == static_cast<Class1*>(&m));
934938d48fSEric Fiselier assert(dynamic_cast<Shared*>(c1) == static_cast<Shared*>(&m));
944938d48fSEric Fiselier assert(dynamic_cast<Class6*>(c1) == 0);
954938d48fSEric Fiselier assert(dynamic_cast<Left*>(c1) == static_cast<Left*>(&m));
964938d48fSEric Fiselier assert(dynamic_cast<Right*>(c1) == static_cast<Right*>(&m));
974938d48fSEric Fiselier assert(dynamic_cast<Main*>(c1) == static_cast<Main*>(&m));
984938d48fSEric Fiselier }
994938d48fSEric Fiselier
1004938d48fSEric Fiselier } // t3
1014938d48fSEric Fiselier
10229e02657SEric Fiselier namespace t4
10329e02657SEric Fiselier {
10429e02657SEric Fiselier
10529e02657SEric Fiselier // PR33439
~C2t4::C210629e02657SEric Fiselier struct C2 { virtual ~C2() {} Pad1 _; };
~C3t4::C310729e02657SEric Fiselier struct C3 { virtual ~C3() {} Pad2 _; };
10829e02657SEric Fiselier struct C4 : C3 { Pad3 _; };
10929e02657SEric Fiselier struct C8 : C2, virtual C4 { Pad4 _; };
11029e02657SEric Fiselier struct C9 : C4, C8 { Pad5 _; };
11129e02657SEric Fiselier
11229e02657SEric Fiselier C9 c9;
11329e02657SEric Fiselier C2 *c2 = &c9;
11429e02657SEric Fiselier
test()11529e02657SEric Fiselier void test()
11629e02657SEric Fiselier {
11729e02657SEric Fiselier assert(dynamic_cast<C2*>(c2) == static_cast<C2*>(&c9));
11829e02657SEric Fiselier assert(dynamic_cast<C3*>(c2) == 0);
11929e02657SEric Fiselier assert(dynamic_cast<C4*>(c2) == 0);
12029e02657SEric Fiselier assert(dynamic_cast<C8*>(c2) == static_cast<C8*>(&c9));
12129e02657SEric Fiselier assert(dynamic_cast<C9*>(c2) == static_cast<C9*>(&c9));
12229e02657SEric Fiselier }
12329e02657SEric Fiselier
12429e02657SEric Fiselier } // t4
12529e02657SEric Fiselier
12629e02657SEric Fiselier namespace t5
12729e02657SEric Fiselier {
12829e02657SEric Fiselier
12929e02657SEric Fiselier // PR33439
~Dummyt5::Dummy13029e02657SEric Fiselier struct Dummy { virtual ~Dummy() {} Pad1 _; };
~Srct5::Src13129e02657SEric Fiselier struct Src { virtual ~Src() {} Pad2 _; };
13229e02657SEric Fiselier struct Dest : Dummy { Pad3 _; };
13329e02657SEric Fiselier struct A1 : Dest { Pad4 _; };
13429e02657SEric Fiselier struct A2 : Dest { Pad5 _; };
13529e02657SEric Fiselier struct Root : Src, A1, A2 { Pad6 _; };
13629e02657SEric Fiselier
13729e02657SEric Fiselier Root root;
13829e02657SEric Fiselier Src *src = &root;
13929e02657SEric Fiselier
test()14029e02657SEric Fiselier void test()
14129e02657SEric Fiselier {
14229e02657SEric Fiselier assert(dynamic_cast<Dummy*>(src) == 0);
14329e02657SEric Fiselier assert(dynamic_cast<Src*>(src) == static_cast<Src*>(&root));
14429e02657SEric Fiselier assert(dynamic_cast<Dest*>(src) == 0);
14529e02657SEric Fiselier assert(dynamic_cast<A1*>(src) == static_cast<A1*>(&root));
14629e02657SEric Fiselier assert(dynamic_cast<A2*>(src) == static_cast<A2*>(&root));
14729e02657SEric Fiselier }
14829e02657SEric Fiselier
14929e02657SEric Fiselier } // t5
15029e02657SEric Fiselier
main(int,char **)151504bc07dSLouis Dionne int main(int, char**)
1524938d48fSEric Fiselier {
1534938d48fSEric Fiselier t1::test();
1544938d48fSEric Fiselier t2::test();
1554938d48fSEric Fiselier t3::test();
15629e02657SEric Fiselier t4::test();
15729e02657SEric Fiselier t5::test();
158504bc07dSLouis Dionne
159504bc07dSLouis Dionne return 0;
1604938d48fSEric Fiselier }
161