brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.3 KiB · cb14fcf Raw
86 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// _Unwind_ForcedUnwind raised exception can be caught by catch (...) and be10// rethrown. If not rethrown, exception_cleanup will be called.11 12// UNSUPPORTED: no-exceptions, c++0313 14// VE only supports SjLj and doesn't provide _Unwind_ForcedUnwind.15// UNSUPPORTED: target={{ve-.*}}16 17// These tests fail on previously released dylibs, investigation needed.18// XFAIL: stdlib=system && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}19// XFAIL: stdlib=system && target={{.+}}-apple-macosx{{11.0|12.0}}20 21#include <stdlib.h>22#include <string.h>23#include <unwind.h>24#include <tuple>25#include <__cxxabi_config.h>26 27static int bits = 0;28 29struct C {30  int bit;31  C(int b) : bit(b) {}32  ~C() { bits |= bit; }33};34 35template <typename T>36struct Stop;37 38template <typename R, typename... Args>39struct Stop<R (*)(Args...)> {40  // The third argument of _Unwind_Stop_Fn is uint64_t in Itanium C++ ABI/LLVM41  // libunwind while _Unwind_Exception_Class in libgcc.42  typedef typename std::tuple_element<2, std::tuple<Args...>>::type type;43 44  static _Unwind_Reason_Code stop(int, _Unwind_Action actions, type,45                                  struct _Unwind_Exception*,46                                  struct _Unwind_Context*, void*) {47    if (actions & _UA_END_OF_STACK)48      abort();49    return _URC_NO_REASON;50  }51};52 53static void cleanup(_Unwind_Reason_Code, struct _Unwind_Exception* exc) {54  bits |= 8;55  delete exc;56}57 58static void forced_unwind() {59  _Unwind_Exception* exc = new _Unwind_Exception;60  memset(&exc->exception_class, 0, sizeof(exc->exception_class));61  exc->exception_cleanup = cleanup;62  _Unwind_ForcedUnwind(exc, Stop<_Unwind_Stop_Fn>::stop, 0);63  abort();64}65 66static void test() {67  try {68    C four(4);69    try {70      C one(1);71      forced_unwind();72    } catch (...) {73      bits |= 2;74      throw;75    }76  } catch (int) {77  } catch (...) {78    // __cxa_end_catch calls cleanup.79  }80}81 82int main(int, char**) {83  test();84  return bits != 15;85}86