1// Copyright (C) 2009-2015 Free Software Foundation, Inc.
2//
3// This file is part of the GNU ISO C++ Library.  This library is free
4// software; you can redistribute it and/or modify it under the
5// terms of the GNU General Public License as published by the
6// Free Software Foundation; either version 3, or (at your option)
7// any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License along
15// with this library; see the file COPYING3.  If not see
16// <http://www.gnu.org/licenses/>.
17
18#include <typeinfo>
19#include <exception>
20#include "unwind.h"
21#include <testsuite_hooks.h>
22
23// Before exception_ptr was introduced, some programs copied
24// part of unwind-cxx.h and used __cxa_get_globals to get at the
25// current exceptionType.  __cxa_exception structure is described in the
26// C++ ABI, so they have the right to assume it works.
27// Ensure it is true.
28
29struct __cxa_exception
30{
31  std::type_info *exceptionType;
32  void (*exceptionDestructor)(void *);
33  std::unexpected_handler unexpectedHandler;
34  std::terminate_handler terminateHandler;
35  __cxa_exception *nextException;
36  int handlerCount;
37#ifdef __ARM_EABI_UNWINDER__
38  __cxa_exception* nextPropagatingException;
39  int propagationCount;
40#else
41  int handlerSwitchValue;
42  const unsigned char *actionRecord;
43  const unsigned char *languageSpecificData;
44  _Unwind_Ptr catchTemp;
45  void *adjustedPtr;
46#endif
47  _Unwind_Exception unwindHeader;
48};
49
50struct __cxa_eh_globals
51{
52  __cxa_exception *caughtExceptions;
53  unsigned int uncaughtExceptions;
54#ifdef __ARM_EABI_UNWINDER__
55  __cxa_exception* propagatingExceptions;
56#endif
57};
58
59extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
60
61// PR libstdc++/38732
62void test01 ()
63{
64  bool test __attribute__((unused)) = true;
65  try {
66    throw 0;
67  } catch(...) {
68    __cxa_exception *exc = __cxa_get_globals()->caughtExceptions;
69    VERIFY ( exc != 0 );
70    VERIFY ( typeid(int) == *exc->exceptionType );
71  }
72  try {
73    throw 0LL;
74  } catch(...) {
75    __cxa_exception *exc = __cxa_get_globals()->caughtExceptions;
76    VERIFY ( exc != 0 );
77    VERIFY ( typeid(long long int) == *exc->exceptionType );
78  }
79  try {
80    throw 0.0;
81  } catch(...) {
82    __cxa_exception *exc = __cxa_get_globals()->caughtExceptions;
83    VERIFY ( exc != 0 );
84    VERIFY ( typeid(double) == *exc->exceptionType );
85  }
86}
87
88int main ()
89{
90  test01 ();
91}
92