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