From 0200472671d0cf18fccbdf8fe34e2fef181718e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 12 Oct 2020 00:51:46 +0300 Subject: [PATCH] test: Add a testcase for cleanup of C++ destructors while doing longjmp For x86_64 and aarch64, this requires https://reviews.llvm.org/D89231. The C++ destructors aren't executed while doing the longjmp (contrary to how it works MSVC's C++ exceptions), but it no longer crashes. --- Dockerfile.dev | 2 +- run-tests.sh | 2 +- test/longjmp-cleanup.cpp | 55 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 test/longjmp-cleanup.cpp diff --git a/Dockerfile.dev b/Dockerfile.dev index 3c4279c..3062985 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -92,7 +92,7 @@ COPY test/*.cpp ./test/ RUN cd test && \ for arch in $TOOLCHAIN_ARCHS; do \ mkdir -p $arch && \ - for test in hello-cpp hello-exception tlstest-main exception-locale exception-reduced global-terminate; do \ + for test in hello-cpp hello-exception tlstest-main exception-locale exception-reduced global-terminate longjmp-cleanup; do \ $arch-w64-mingw32-clang++ $test.cpp -o $arch/$test.exe || exit 1; \ done; \ for test in hello-exception; do \ diff --git a/run-tests.sh b/run-tests.sh index c215ef5..6a985a9 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -63,7 +63,7 @@ TESTS_C_DLL="autoimport-lib" TESTS_C_LINK_DLL="autoimport-main" TESTS_C_NO_BUILTIN="crt-test" TESTS_C_ANSI_STDIO="crt-test" -TESTS_CPP="hello-cpp global-terminate" +TESTS_CPP="hello-cpp global-terminate longjmp-cleanup" TESTS_CPP_LOAD_DLL="tlstest-main" TESTS_CPP_EXCEPTIONS="hello-exception exception-locale exception-reduced" TESTS_CPP_STATIC="hello-exception" diff --git a/test/longjmp-cleanup.cpp b/test/longjmp-cleanup.cpp new file mode 100644 index 0000000..3537ddc --- /dev/null +++ b/test/longjmp-cleanup.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020 Martin Storsjo + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +jmp_buf jmp; + +class RecurseClass { +public: + RecurseClass(int v) : val(v) { + fprintf(stderr, "ctor %d\n", val); + } + ~RecurseClass() { + fprintf(stderr, "dtor %d\n", val); + } +private: + int val; +}; + +void recurse(int val) { + RecurseClass obj(val); + if (val == 0) { + longjmp(jmp, 1); + } + if (val == 5) { + if (!setjmp(jmp)) + recurse(val - 1); + else + fprintf(stderr, "returned from setjmp\n"); + } else { + recurse(val - 1); + } + fprintf(stderr, "finishing function recurse %d\n", val); +} + +int main(int argc, char* argv[]) { + recurse(10); + return 0; +}