/ test / unwind_05.pass.cpp
unwind_05.pass.cpp
  1  //===------------------------- unwind_05.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  // REQUIRES: c++03 || c++11 || c++14
 11  
 12  #include <exception>
 13  #include <stdlib.h>
 14  #include <assert.h>
 15  
 16  #if defined(__GNUC__)
 17  #pragma GCC diagnostic ignored "-Wunreachable-code"
 18  #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated
 19  #endif
 20  
 21  struct A
 22  {
 23      static int count;
 24      int id_;
 25      A() : id_(++count) {}
 26      ~A() {assert(id_ == count--);}
 27  
 28  private:
 29      A(const A&);
 30      A& operator=(const A&);
 31  };
 32  
 33  int A::count = 0;
 34  
 35  struct B
 36  {
 37      static int count;
 38      int id_;
 39      B() : id_(++count) {}
 40      ~B() {assert(id_ == count--);}
 41  
 42  private:
 43      B(const B&);
 44      B& operator=(const B&);
 45  };
 46  
 47  int B::count = 0;
 48  
 49  struct C
 50  {
 51      static int count;
 52      int id_;
 53      C() : id_(++count) {}
 54      ~C() {assert(id_ == count--);}
 55  
 56  private:
 57      C(const C&);
 58      C& operator=(const C&);
 59  };
 60  
 61  int C::count = 0;
 62  
 63  void f2()
 64  {
 65      C c;
 66      A a;
 67      throw 55;
 68      B b;
 69  }
 70  
 71  void f1() throw (long, char, double, std::bad_exception)
 72  {
 73      A a;
 74      B b;
 75      f2();
 76      C c;
 77  }
 78  
 79  void u_handler()
 80  {
 81      throw;
 82  }
 83  
 84  int main(int, char**)
 85  {
 86      std::set_unexpected(u_handler);
 87      try
 88      {
 89          f1();
 90          assert(false);
 91      }
 92      catch (int* i)
 93      {
 94          assert(false);
 95      }
 96      catch (long i)
 97      {
 98          assert(false);
 99      }
100      catch (int i)
101      {
102          assert(false);
103      }
104      catch (char c)
105      {
106          assert(false);
107      }
108      catch (const std::bad_exception& e)
109      {
110          assert(true);
111      }
112      catch (...)
113      {
114          assert(false);
115      }
116      assert(A::count == 0);
117      assert(B::count == 0);
118      assert(C::count == 0);
119  
120      return 0;
121  }