1 //===------------------------- catch_ptr_02.cpp ---------------------------===//
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 // UNSUPPORTED: no-exceptions
10 
11 // FIXME: GCC doesn't allow turning off the warning for exceptions being caught
12 //        by earlier handlers, which this test is exercising. We have to disable
13 //        warnings altogether to remove the error.
14 //        See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97675.
15 // ADDITIONAL_COMPILE_FLAGS: -Wno-error
16 
17 #include <cassert>
18 
19 // Clang emits  warnings about exceptions of type 'Child' being caught by
20 // an earlier handler of type 'Base'. Congrats clang, you've just
21 // diagnosed the behavior under test.
22 #if defined(__clang__)
23 #pragma clang diagnostic ignored "-Wexceptions"
24 #endif
25 
26 #if __cplusplus < 201103L
27 #define DISABLE_NULLPTR_TESTS
28 #endif
29 
30 struct  A {};
31 A a;
32 const A ca = A();
33 
34 void test1 ()
35 {
36     try
37     {
38         throw &a;
39         assert(false);
40     }
41     catch ( const A* )
42     {
43     }
44     catch ( A *)
45     {
46         assert (false);
47     }
48 }
49 
50 void test2 ()
51 {
52     try
53      {
54         throw &a;
55         assert(false);
56     }
57     catch ( A* )
58     {
59     }
60     catch ( const A *)
61     {
62          assert (false);
63     }
64 }
65 
66 void test3 ()
67 {
68     try
69     {
70         throw &ca;
71         assert(false);
72     }
73     catch ( const A* )
74     {
75     }
76     catch ( A *)
77     {
78         assert (false);
79     }
80 }
81 
82 void test4 ()
83 {
84     try
85     {
86         throw &ca;
87         assert(false);
88     }
89     catch ( A *)
90     {
91         assert (false);
92     }
93     catch ( const A* )
94     {
95     }
96 }
97 
98 struct base1 {int x;};
99 struct base2 {int x;};
100 struct derived : base1, base2 {};
101 
102 void test5 ()
103 {
104     try
105     {
106         throw (derived*)0;
107         assert(false);
108     }
109     catch (base2 *p) {
110         assert (p == 0);
111     }
112     catch (...)
113     {
114         assert (false);
115     }
116 }
117 
118 void test6 ()
119 {
120 #if !defined(DISABLE_NULLPTR_TESTS)
121     try
122     {
123         throw nullptr;
124         assert(false);
125     }
126     catch (base2 *p) {
127         assert (p == nullptr);
128     }
129     catch (...)
130     {
131         assert (false);
132     }
133 #endif
134 }
135 
136 void test7 ()
137 {
138     try
139     {
140         throw (derived*)12;
141         assert(false);
142     }
143     catch (base2 *p) {
144         assert ((unsigned long)p == 12+sizeof(base1));
145     }
146     catch (...)
147     {
148         assert (false);
149     }
150 }
151 
152 
153 struct vBase {};
154 struct vDerived : virtual public vBase {};
155 
156 void test8 ()
157 {
158     vDerived derived;
159     try
160     {
161         throw &derived;
162         assert(false);
163     }
164     catch (vBase *p) {
165         assert(p != 0);
166     }
167     catch (...)
168     {
169         assert (false);
170     }
171 }
172 
173 void test9 ()
174 {
175 #if !defined(DISABLE_NULLPTR_TESTS)
176     try
177     {
178         throw nullptr;
179         assert(false);
180     }
181     catch (vBase *p) {
182         assert(p == 0);
183     }
184     catch (...)
185     {
186         assert (false);
187     }
188 #endif
189 }
190 
191 void test10 ()
192 {
193     try
194     {
195         throw (vDerived*)0;
196         assert(false);
197     }
198     catch (vBase *p) {
199         assert(p == 0);
200     }
201     catch (...)
202     {
203         assert (false);
204     }
205 }
206 
207 int main(int, char**)
208 {
209     test1();
210     test2();
211     test3();
212     test4();
213     test5();
214     test6();
215     test7();
216     test8();
217     test9();
218     test10();
219 
220     return 0;
221 }
222