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