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 // type_traits
10 
11 // is_destructible
12 
13 // Prevent warning when testing the Abstract test type.
14 #if defined(__clang__)
15 #pragma clang diagnostic ignored "-Wdelete-non-virtual-dtor"
16 #endif
17 
18 #include <type_traits>
19 #include "test_macros.h"
20 
21 
22 template <class T>
test_is_destructible()23 void test_is_destructible()
24 {
25     static_assert( std::is_destructible<T>::value, "");
26     static_assert( std::is_destructible<const T>::value, "");
27     static_assert( std::is_destructible<volatile T>::value, "");
28     static_assert( std::is_destructible<const volatile T>::value, "");
29 #if TEST_STD_VER > 14
30     static_assert( std::is_destructible_v<T>, "");
31     static_assert( std::is_destructible_v<const T>, "");
32     static_assert( std::is_destructible_v<volatile T>, "");
33     static_assert( std::is_destructible_v<const volatile T>, "");
34 #endif
35 }
36 
37 template <class T>
test_is_not_destructible()38 void test_is_not_destructible()
39 {
40     static_assert(!std::is_destructible<T>::value, "");
41     static_assert(!std::is_destructible<const T>::value, "");
42     static_assert(!std::is_destructible<volatile T>::value, "");
43     static_assert(!std::is_destructible<const volatile T>::value, "");
44 #if TEST_STD_VER > 14
45     static_assert(!std::is_destructible_v<T>, "");
46     static_assert(!std::is_destructible_v<const T>, "");
47     static_assert(!std::is_destructible_v<volatile T>, "");
48     static_assert(!std::is_destructible_v<const volatile T>, "");
49 #endif
50 }
51 
52 class Empty {};
53 
54 class NotEmpty
55 {
56     virtual ~NotEmpty();
57 };
58 
59 union Union {};
60 
61 struct bit_zero
62 {
63     int :  0;
64 };
65 
66 struct A
67 {
68     ~A();
69 };
70 
71 typedef void (Function) ();
72 
73 struct PublicAbstract                    { public:    virtual void foo() = 0; };
74 struct ProtectedAbstract                 { protected: virtual void foo() = 0; };
75 struct PrivateAbstract                   { private:   virtual void foo() = 0; };
76 
~PublicDestructorPublicDestructor77 struct PublicDestructor                  { public:    ~PublicDestructor() {}};
~ProtectedDestructorProtectedDestructor78 struct ProtectedDestructor               { protected: ~ProtectedDestructor() {}};
~PrivateDestructorPrivateDestructor79 struct PrivateDestructor                 { private:   ~PrivateDestructor() {}};
80 
~VirtualPublicDestructorVirtualPublicDestructor81 struct VirtualPublicDestructor           { public:    virtual ~VirtualPublicDestructor() {}};
~VirtualProtectedDestructorVirtualProtectedDestructor82 struct VirtualProtectedDestructor        { protected: virtual ~VirtualProtectedDestructor() {}};
~VirtualPrivateDestructorVirtualPrivateDestructor83 struct VirtualPrivateDestructor          { private:   virtual ~VirtualPrivateDestructor() {}};
84 
85 struct PurePublicDestructor              { public:    virtual ~PurePublicDestructor() = 0; };
86 struct PureProtectedDestructor           { protected: virtual ~PureProtectedDestructor() = 0; };
87 struct PurePrivateDestructor             { private:   virtual ~PurePrivateDestructor() = 0; };
88 
89 #if TEST_STD_VER >= 11
90 struct DeletedPublicDestructor           { public:    ~DeletedPublicDestructor() = delete; };
91 struct DeletedProtectedDestructor        { protected: ~DeletedProtectedDestructor() = delete; };
92 struct DeletedPrivateDestructor          { private:   ~DeletedPrivateDestructor() = delete; };
93 
94 struct DeletedVirtualPublicDestructor    { public:    virtual ~DeletedVirtualPublicDestructor() = delete; };
95 struct DeletedVirtualProtectedDestructor { protected: virtual ~DeletedVirtualProtectedDestructor() = delete; };
96 struct DeletedVirtualPrivateDestructor   { private:   virtual ~DeletedVirtualPrivateDestructor() = delete; };
97 #endif
98 
99 
main(int,char **)100 int main(int, char**)
101 {
102     test_is_destructible<A>();
103     test_is_destructible<int&>();
104     test_is_destructible<Union>();
105     test_is_destructible<Empty>();
106     test_is_destructible<int>();
107     test_is_destructible<double>();
108     test_is_destructible<int*>();
109     test_is_destructible<const int*>();
110     test_is_destructible<char[3]>();
111     test_is_destructible<bit_zero>();
112     test_is_destructible<int[3]>();
113     test_is_destructible<ProtectedAbstract>();
114     test_is_destructible<PublicAbstract>();
115     test_is_destructible<PrivateAbstract>();
116     test_is_destructible<PublicDestructor>();
117     test_is_destructible<VirtualPublicDestructor>();
118     test_is_destructible<PurePublicDestructor>();
119 
120     test_is_not_destructible<int[]>();
121     test_is_not_destructible<void>();
122     test_is_not_destructible<Function>();
123 
124 #if TEST_STD_VER >= 11
125     // Test access controlled destructors
126     test_is_not_destructible<ProtectedDestructor>();
127     test_is_not_destructible<PrivateDestructor>();
128     test_is_not_destructible<VirtualProtectedDestructor>();
129     test_is_not_destructible<VirtualPrivateDestructor>();
130     test_is_not_destructible<PureProtectedDestructor>();
131     test_is_not_destructible<PurePrivateDestructor>();
132 
133     // Test deleted constructors
134     test_is_not_destructible<DeletedPublicDestructor>();
135     test_is_not_destructible<DeletedProtectedDestructor>();
136     test_is_not_destructible<DeletedPrivateDestructor>();
137     //test_is_not_destructible<DeletedVirtualPublicDestructor>(); // previously failed due to clang bug #20268
138     test_is_not_destructible<DeletedVirtualProtectedDestructor>();
139     test_is_not_destructible<DeletedVirtualPrivateDestructor>();
140 
141     // Test private destructors
142     test_is_not_destructible<NotEmpty>();
143 #endif
144 
145 
146   return 0;
147 }
148