brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.2 KiB · e852ab5 Raw
83 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// Let's run ForcedUnwind until it reaches end of the stack, this test simulates10// what pthread_cancel does.11 12// UNSUPPORTED: c++0313// UNSUPPORTED: no-threads14// UNSUPPORTED: no-exceptions15 16// VE only supports SjLj and doesn't provide _Unwind_ForcedUnwind.17// UNSUPPORTED: target={{ve-.*}}18 19#include <assert.h>20#include <exception>21#include <stdlib.h>22#include <string.h>23#include <unwind.h>24#include <thread>25#include <tuple>26#include <__cxxabi_config.h>27 28// TODO: dump version back to 14 once clang is updated on the CI.29#if defined(_LIBCXXABI_ARM_EHABI) && defined(__clang__) && __clang_major__ < 1530// _Unwind_ForcedUnwind is not available or broken before version 14.31int main(int, char**) { return 0; }32 33#else34static bool destructorCalled = false;35 36struct myClass {37  myClass() {}38  ~myClass() {39    assert(destructorCalled == false);40    destructorCalled = true;41  };42};43 44template <typename T>45struct Stop;46 47template <typename R, typename... Args>48struct Stop<R (*)(Args...)> {49  // The third argument of _Unwind_Stop_Fn is uint64_t in Itanium C++ ABI/LLVM50  // libunwind while _Unwind_Exception_Class in libgcc.51  typedef typename std::tuple_element<2, std::tuple<Args...>>::type type;52 53  static _Unwind_Reason_Code stop(int, _Unwind_Action actions, type, _Unwind_Exception*, struct _Unwind_Context*,54                                  void*) {55    if (actions & _UA_END_OF_STACK) {56      assert(destructorCalled == true);57      exit(0);58    }59    return _URC_NO_REASON;60  }61};62 63static void forced_unwind() {64  _Unwind_Exception* exc = new _Unwind_Exception;65  memset(&exc->exception_class, 0, sizeof(exc->exception_class));66  exc->exception_cleanup = 0;67  _Unwind_ForcedUnwind(exc, Stop<_Unwind_Stop_Fn>::stop, 0);68  abort();69}70 71__attribute__((__noinline__)) static void test() {72  myClass c{};73  forced_unwind();74  abort();75}76 77int main(int, char**) {78  std::thread t{test};79  t.join();80  return -1;81}82#endif83