mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
third_party/libcxxabi: Add test suite (#1076)
Added the `libcxxabi` test suite as found in LLVM 17.0.6. Some tests that do not apply to the current configuration of comsopolitan are not added. These include: - `backtrace_test`, `forced_unwind*`: Use unwind function unsupported in SjLj mode. - `noexception*`: Designed to test `libcxxabi` in no exceptions mode. Some tests are added but not enabled due to bugs specific to GCC or cosmopolitan. These are clearly indicated in the `BUILD.mk` file.
This commit is contained in:
parent
8fb24a8f88
commit
b0566348b2
65 changed files with 43262 additions and 2 deletions
1
Makefile
1
Makefile
|
@ -330,6 +330,7 @@ include third_party/python/BUILD.mk
|
||||||
include tool/build/BUILD.mk
|
include tool/build/BUILD.mk
|
||||||
include tool/curl/BUILD.mk
|
include tool/curl/BUILD.mk
|
||||||
include third_party/qemu/BUILD.mk
|
include third_party/qemu/BUILD.mk
|
||||||
|
include third_party/libcxxabi/test/BUILD.mk
|
||||||
include examples/BUILD.mk
|
include examples/BUILD.mk
|
||||||
include examples/pyapp/BUILD.mk
|
include examples/pyapp/BUILD.mk
|
||||||
include examples/pylife/BUILD.mk
|
include examples/pylife/BUILD.mk
|
||||||
|
|
5
third_party/libcxxabi/BUILD.mk
vendored
5
third_party/libcxxabi/BUILD.mk
vendored
|
@ -107,6 +107,7 @@ THIRD_PARTY_LIBCXXABI_CHECKS = $(foreach x,$(THIRD_PARTY_LIBCXXABI_ARTIFACTS),$(
|
||||||
THIRD_PARTY_LIBCXXABI_OBJS = $(foreach x,$(THIRD_PARTY_LIBCXXABI_ARTIFACTS),$($(x)_OBJS))
|
THIRD_PARTY_LIBCXXABI_OBJS = $(foreach x,$(THIRD_PARTY_LIBCXXABI_ARTIFACTS),$($(x)_OBJS))
|
||||||
|
|
||||||
.PHONY: o/$(MODE)/third_party/libcxxabi
|
.PHONY: o/$(MODE)/third_party/libcxxabi
|
||||||
o/$(MODE)/third_party/libcxxabi: \
|
o/$(MODE)/third_party/libcxxabi: \
|
||||||
$(THIRD_PARTY_LIBCXXABI_CHECKS) \
|
o/$(MODE)/third_party/libcxxabi/test \
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_CHECKS) \
|
||||||
$(THIRD_PARTY_LIBCXXABI_A)
|
$(THIRD_PARTY_LIBCXXABI_A)
|
||||||
|
|
2
third_party/libcxxabi/README.cosmo
vendored
2
third_party/libcxxabi/README.cosmo
vendored
|
@ -15,4 +15,6 @@ LOCAL CHANGES
|
||||||
|
|
||||||
- Add <__memory/aligned_alloc.h> (contains a few inline functions) from
|
- Add <__memory/aligned_alloc.h> (contains a few inline functions) from
|
||||||
upstream libcxx.
|
upstream libcxx.
|
||||||
|
- Add <test/support/make_test_thread.hh> and <test/support/test_macros.hh>
|
||||||
|
from upstream libcxx.
|
||||||
- Enable __cxa_thread_atexit for Cosmopolitan.
|
- Enable __cxa_thread_atexit for Cosmopolitan.
|
||||||
|
|
24
third_party/libcxxabi/libcxx/test/support/make_test_thread.hh
vendored
Normal file
24
third_party/libcxxabi/libcxx/test/support/make_test_thread.hh
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef TEST_SUPPORT_MAKE_TEST_THREAD_H
|
||||||
|
#define TEST_SUPPORT_MAKE_TEST_THREAD_H
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace support {
|
||||||
|
|
||||||
|
template <class F, class ...Args>
|
||||||
|
std::thread make_test_thread(F&& f, Args&& ...args) {
|
||||||
|
return std::thread(std::forward<F>(f), std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace support
|
||||||
|
|
||||||
|
#endif // TEST_SUPPORT_MAKE_TEST_THREAD_H
|
452
third_party/libcxxabi/libcxx/test/support/test_macros.hh
vendored
Normal file
452
third_party/libcxxabi/libcxx/test/support/test_macros.hh
vendored
Normal file
|
@ -0,0 +1,452 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef SUPPORT_TEST_MACROS_HPP
|
||||||
|
#define SUPPORT_TEST_MACROS_HPP
|
||||||
|
|
||||||
|
// Attempt to get STL specific macros like _LIBCPP_VERSION using the most
|
||||||
|
// minimal header possible. If we're testing libc++, we should use `<__config>`.
|
||||||
|
// If <__config> isn't available, fall back to <ciso646>.
|
||||||
|
#ifdef __has_include
|
||||||
|
# if __has_include("third_party/libcxx/__config")
|
||||||
|
# include "third_party/libcxx/__config"
|
||||||
|
# define TEST_IMP_INCLUDED_HEADER
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#ifndef TEST_IMP_INCLUDED_HEADER
|
||||||
|
#include "third_party/libcxx/ciso646"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TEST_STRINGIZE_IMPL(...) #__VA_ARGS__
|
||||||
|
#define TEST_STRINGIZE(...) TEST_STRINGIZE_IMPL(__VA_ARGS__)
|
||||||
|
|
||||||
|
#define TEST_CONCAT1(X, Y) X##Y
|
||||||
|
#define TEST_CONCAT(X, Y) TEST_CONCAT1(X, Y)
|
||||||
|
|
||||||
|
#ifdef __has_feature
|
||||||
|
#define TEST_HAS_FEATURE(X) __has_feature(X)
|
||||||
|
#else
|
||||||
|
#define TEST_HAS_FEATURE(X) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __has_include
|
||||||
|
#define __has_include(...) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __has_extension
|
||||||
|
#define TEST_HAS_EXTENSION(X) __has_extension(X)
|
||||||
|
#else
|
||||||
|
#define TEST_HAS_EXTENSION(X) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __has_warning
|
||||||
|
#define TEST_HAS_WARNING(X) __has_warning(X)
|
||||||
|
#else
|
||||||
|
#define TEST_HAS_WARNING(X) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __has_builtin
|
||||||
|
#define TEST_HAS_BUILTIN(X) __has_builtin(X)
|
||||||
|
#else
|
||||||
|
#define TEST_HAS_BUILTIN(X) 0
|
||||||
|
#endif
|
||||||
|
#ifdef __is_identifier
|
||||||
|
// '__is_identifier' returns '0' if '__x' is a reserved identifier provided by
|
||||||
|
// the compiler and '1' otherwise.
|
||||||
|
#define TEST_HAS_BUILTIN_IDENTIFIER(X) !__is_identifier(X)
|
||||||
|
#else
|
||||||
|
#define TEST_HAS_BUILTIN_IDENTIFIER(X) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__EDG__)
|
||||||
|
# define TEST_COMPILER_EDG
|
||||||
|
#elif defined(__clang__)
|
||||||
|
# define TEST_COMPILER_CLANG
|
||||||
|
# if defined(__apple_build_version__)
|
||||||
|
# define TEST_COMPILER_APPLE_CLANG
|
||||||
|
# endif
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
# define TEST_COMPILER_MSVC
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
# define TEST_COMPILER_GCC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__apple_build_version__)
|
||||||
|
// Given AppleClang XX.Y.Z, TEST_APPLE_CLANG_VER is XXYZ (e.g. AppleClang 14.0.3 => 1403)
|
||||||
|
#define TEST_APPLE_CLANG_VER (__apple_build_version__ / 10000)
|
||||||
|
#elif defined(__clang_major__)
|
||||||
|
#define TEST_CLANG_VER (__clang_major__ * 100) + __clang_minor__
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
// Given GCC XX.YY.ZZ, TEST_GCC_VER is XXYYZZ
|
||||||
|
#define TEST_GCC_VER ((__GNUC__ * 10000) + (__GNUC_MINOR__ * 100) + __GNUC_PATCHLEVEL__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Make a nice name for the standard version */
|
||||||
|
#ifndef TEST_STD_VER
|
||||||
|
#if __cplusplus <= 199711L
|
||||||
|
# define TEST_STD_VER 3
|
||||||
|
#elif __cplusplus <= 201103L
|
||||||
|
# define TEST_STD_VER 11
|
||||||
|
#elif __cplusplus <= 201402L
|
||||||
|
# define TEST_STD_VER 14
|
||||||
|
#elif __cplusplus <= 201703L
|
||||||
|
# define TEST_STD_VER 17
|
||||||
|
#elif __cplusplus <= 202002L
|
||||||
|
# define TEST_STD_VER 20
|
||||||
|
#elif __cplusplus <= 202302L
|
||||||
|
# define TEST_STD_VER 23
|
||||||
|
#else
|
||||||
|
# define TEST_STD_VER 99 // greater than current standard
|
||||||
|
// This is deliberately different than _LIBCPP_STD_VER to discourage matching them up.
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Attempt to deduce the GLIBC version
|
||||||
|
#if (defined(__has_include) && __has_include(<features.h>)) || \
|
||||||
|
defined(__linux__)
|
||||||
|
#include <features.h>
|
||||||
|
#if defined(__GLIBC_PREREQ)
|
||||||
|
#define TEST_HAS_GLIBC
|
||||||
|
#define TEST_GLIBC_PREREQ(major, minor) __GLIBC_PREREQ(major, minor)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TEST_STD_VER >= 11
|
||||||
|
# define TEST_ALIGNOF(...) alignof(__VA_ARGS__)
|
||||||
|
# define TEST_ALIGNAS(...) alignas(__VA_ARGS__)
|
||||||
|
# define TEST_CONSTEXPR constexpr
|
||||||
|
# define TEST_NOEXCEPT noexcept
|
||||||
|
# define TEST_NOEXCEPT_FALSE noexcept(false)
|
||||||
|
# define TEST_NOEXCEPT_COND(...) noexcept(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
# if defined(TEST_COMPILER_CLANG)
|
||||||
|
# define TEST_ALIGNOF(...) _Alignof(__VA_ARGS__)
|
||||||
|
# else
|
||||||
|
# define TEST_ALIGNOF(...) __alignof(__VA_ARGS__)
|
||||||
|
# endif
|
||||||
|
# define TEST_ALIGNAS(...) __attribute__((__aligned__(__VA_ARGS__)))
|
||||||
|
# define TEST_CONSTEXPR
|
||||||
|
# define TEST_NOEXCEPT throw()
|
||||||
|
# define TEST_NOEXCEPT_FALSE
|
||||||
|
# define TEST_NOEXCEPT_COND(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TEST_STD_VER >= 11
|
||||||
|
# define TEST_THROW_SPEC(...)
|
||||||
|
#else
|
||||||
|
# define TEST_THROW_SPEC(...) throw(__VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cpp_lib_is_constant_evaluated) && __cpp_lib_is_constant_evaluated >= 201811L
|
||||||
|
# define TEST_IS_CONSTANT_EVALUATED std::is_constant_evaluated()
|
||||||
|
#elif TEST_HAS_BUILTIN(__builtin_is_constant_evaluated)
|
||||||
|
# define TEST_IS_CONSTANT_EVALUATED __builtin_is_constant_evaluated()
|
||||||
|
#else
|
||||||
|
# define TEST_IS_CONSTANT_EVALUATED false
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TEST_STD_VER >= 14
|
||||||
|
# define TEST_CONSTEXPR_CXX14 constexpr
|
||||||
|
#else
|
||||||
|
# define TEST_CONSTEXPR_CXX14
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TEST_STD_VER >= 17
|
||||||
|
# define TEST_CONSTEXPR_CXX17 constexpr
|
||||||
|
#else
|
||||||
|
# define TEST_CONSTEXPR_CXX17
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TEST_STD_VER >= 20
|
||||||
|
# define TEST_CONSTEXPR_CXX20 constexpr
|
||||||
|
#else
|
||||||
|
# define TEST_CONSTEXPR_CXX20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TEST_STD_VER >= 23
|
||||||
|
# define TEST_CONSTEXPR_CXX23 constexpr
|
||||||
|
#else
|
||||||
|
# define TEST_CONSTEXPR_CXX23
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TEST_ALIGNAS_TYPE(...) TEST_ALIGNAS(TEST_ALIGNOF(__VA_ARGS__))
|
||||||
|
|
||||||
|
#if !TEST_HAS_FEATURE(cxx_rtti) && !defined(__cpp_rtti) \
|
||||||
|
&& !defined(__GXX_RTTI)
|
||||||
|
#define TEST_HAS_NO_RTTI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(TEST_HAS_NO_RTTI)
|
||||||
|
# define RTTI_ASSERT(X) assert(X)
|
||||||
|
#else
|
||||||
|
# define RTTI_ASSERT(X)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !TEST_HAS_FEATURE(cxx_exceptions) && !defined(__cpp_exceptions) \
|
||||||
|
&& !defined(__EXCEPTIONS)
|
||||||
|
#define TEST_HAS_NO_EXCEPTIONS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TEST_HAS_FEATURE(address_sanitizer) || TEST_HAS_FEATURE(hwaddress_sanitizer) || \
|
||||||
|
TEST_HAS_FEATURE(memory_sanitizer) || TEST_HAS_FEATURE(thread_sanitizer)
|
||||||
|
#define TEST_HAS_SANITIZERS
|
||||||
|
#define TEST_IS_EXECUTED_IN_A_SLOW_ENVIRONMENT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_LIBCPP_NORETURN)
|
||||||
|
#define TEST_NORETURN _LIBCPP_NORETURN
|
||||||
|
#else
|
||||||
|
#define TEST_NORETURN [[noreturn]]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) || \
|
||||||
|
(!(TEST_STD_VER > 14 || \
|
||||||
|
(defined(__cpp_aligned_new) && __cpp_aligned_new >= 201606L)))
|
||||||
|
#define TEST_HAS_NO_ALIGNED_ALLOCATION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TEST_STD_VER > 17
|
||||||
|
#define TEST_CONSTINIT constinit
|
||||||
|
#elif defined(_LIBCPP_CONSTINIT)
|
||||||
|
#define TEST_CONSTINIT _LIBCPP_CONSTINIT
|
||||||
|
#else
|
||||||
|
#define TEST_CONSTINIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TEST_STD_VER < 11
|
||||||
|
#define ASSERT_NOEXCEPT(...)
|
||||||
|
#define ASSERT_NOT_NOEXCEPT(...)
|
||||||
|
#else
|
||||||
|
#define ASSERT_NOEXCEPT(...) \
|
||||||
|
static_assert(noexcept(__VA_ARGS__), "Operation must be noexcept")
|
||||||
|
|
||||||
|
#define ASSERT_NOT_NOEXCEPT(...) \
|
||||||
|
static_assert(!noexcept(__VA_ARGS__), "Operation must NOT be noexcept")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Macros for testing libc++ specific behavior and extensions */
|
||||||
|
#if defined(_LIBCPP_VERSION)
|
||||||
|
#define LIBCPP_ASSERT(...) assert(__VA_ARGS__)
|
||||||
|
#define LIBCPP_STATIC_ASSERT(...) static_assert(__VA_ARGS__)
|
||||||
|
#define LIBCPP_ASSERT_NOEXCEPT(...) ASSERT_NOEXCEPT(__VA_ARGS__)
|
||||||
|
#define LIBCPP_ASSERT_NOT_NOEXCEPT(...) ASSERT_NOT_NOEXCEPT(__VA_ARGS__)
|
||||||
|
#define LIBCPP_ONLY(...) __VA_ARGS__
|
||||||
|
#else
|
||||||
|
#define LIBCPP_ASSERT(...) static_assert(true, "")
|
||||||
|
#define LIBCPP_STATIC_ASSERT(...) static_assert(true, "")
|
||||||
|
#define LIBCPP_ASSERT_NOEXCEPT(...) static_assert(true, "")
|
||||||
|
#define LIBCPP_ASSERT_NOT_NOEXCEPT(...) static_assert(true, "")
|
||||||
|
#define LIBCPP_ONLY(...) static_assert(true, "")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_cpp_attribute(nodiscard)
|
||||||
|
# define TEST_NODISCARD [[nodiscard]]
|
||||||
|
#else
|
||||||
|
# define TEST_NODISCARD
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TEST_IGNORE_NODISCARD (void)
|
||||||
|
|
||||||
|
namespace test_macros_detail {
|
||||||
|
template <class T, class U>
|
||||||
|
struct is_same { enum { value = 0};} ;
|
||||||
|
template <class T>
|
||||||
|
struct is_same<T, T> { enum {value = 1}; };
|
||||||
|
} // namespace test_macros_detail
|
||||||
|
|
||||||
|
#define ASSERT_SAME_TYPE(...) \
|
||||||
|
static_assert((test_macros_detail::is_same<__VA_ARGS__>::value), \
|
||||||
|
"Types differ unexpectedly")
|
||||||
|
|
||||||
|
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||||
|
#define TEST_THROW(...) throw __VA_ARGS__
|
||||||
|
#else
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define TEST_THROW(...) __builtin_abort()
|
||||||
|
#else
|
||||||
|
#include "libc/isystem/stdlib.h"
|
||||||
|
#define TEST_THROW(...) ::abort()
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
|
template <class Tp>
|
||||||
|
inline
|
||||||
|
void DoNotOptimize(Tp const& value) {
|
||||||
|
asm volatile("" : : "r,m"(value) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Tp>
|
||||||
|
inline void DoNotOptimize(Tp& value) {
|
||||||
|
#if defined(__clang__)
|
||||||
|
asm volatile("" : "+r,m"(value) : : "memory");
|
||||||
|
#else
|
||||||
|
asm volatile("" : "+m,r"(value) : : "memory");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#include <intrin.h>
|
||||||
|
template <class Tp>
|
||||||
|
inline void DoNotOptimize(Tp const& value) {
|
||||||
|
const volatile void* volatile unused = __builtin_addressof(value);
|
||||||
|
static_cast<void>(unused);
|
||||||
|
_ReadWriteBarrier();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define TEST_ALWAYS_INLINE __attribute__((always_inline))
|
||||||
|
#define TEST_NOINLINE __attribute__((noinline))
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define TEST_ALWAYS_INLINE __forceinline
|
||||||
|
#define TEST_NOINLINE __declspec(noinline)
|
||||||
|
#else
|
||||||
|
#define TEST_ALWAYS_INLINE
|
||||||
|
#define TEST_NOINLINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define TEST_NOT_WIN32(...) ((void)0)
|
||||||
|
#else
|
||||||
|
#define TEST_NOT_WIN32(...) __VA_ARGS__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(TEST_WINDOWS_DLL) ||defined(__MVS__) || defined(_AIX)
|
||||||
|
// Macros for waiving cases when we can't count allocations done within
|
||||||
|
// the library implementation.
|
||||||
|
//
|
||||||
|
// On Windows, when libc++ is built as a DLL, references to operator new/delete
|
||||||
|
// within the DLL are bound at link time to the operator new/delete within
|
||||||
|
// the library; replacing them in the user executable doesn't override the
|
||||||
|
// calls within the library.
|
||||||
|
//
|
||||||
|
// The same goes on IBM zOS.
|
||||||
|
// The same goes on AIX.
|
||||||
|
#define ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(...) ((void)(__VA_ARGS__))
|
||||||
|
#define TEST_SUPPORTS_LIBRARY_INTERNAL_ALLOCATIONS 0
|
||||||
|
#else
|
||||||
|
#define ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(...) assert(__VA_ARGS__)
|
||||||
|
#define TEST_SUPPORTS_LIBRARY_INTERNAL_ALLOCATIONS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(TEST_WINDOWS_DLL) && !defined(_MSC_VER)) || \
|
||||||
|
defined(__MVS__)
|
||||||
|
// Normally, a replaced e.g. 'operator new' ends up used if the user code
|
||||||
|
// does a call to e.g. 'operator new[]'; it's enough to replace the base
|
||||||
|
// versions and have it override all of them.
|
||||||
|
//
|
||||||
|
// When the fallback operators are located within the libc++ library and we
|
||||||
|
// can't override the calls within it (see above), this fallback mechanism
|
||||||
|
// doesn't work either.
|
||||||
|
//
|
||||||
|
// On Windows, when using the MSVC vcruntime, the operator new/delete fallbacks
|
||||||
|
// are linked separately from the libc++ library, linked statically into
|
||||||
|
// the end user executable, and these fallbacks work even in DLL configurations.
|
||||||
|
// In MinGW configurations when built as a DLL, and on zOS, these fallbacks
|
||||||
|
// don't work though.
|
||||||
|
#define ASSERT_WITH_OPERATOR_NEW_FALLBACKS(...) ((void)(__VA_ARGS__))
|
||||||
|
#else
|
||||||
|
#define ASSERT_WITH_OPERATOR_NEW_FALLBACKS(...) assert(__VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define TEST_WIN_NO_FILESYSTEM_PERMS_NONE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Support for carving out parts of the test suite, like removing wide characters, etc.
|
||||||
|
#if defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
|
||||||
|
# define TEST_HAS_NO_WIDE_CHARACTERS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_LIBCPP_HAS_NO_UNICODE)
|
||||||
|
# define TEST_HAS_NO_UNICODE
|
||||||
|
#elif defined(_MSVC_EXECUTION_CHARACTER_SET) && _MSVC_EXECUTION_CHARACTER_SET != 65001
|
||||||
|
# define TEST_HAS_NO_UNICODE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_LIBCPP_HAS_NO_INT128) || defined(_MSVC_STL_VERSION)
|
||||||
|
# define TEST_HAS_NO_INT128
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_LIBCPP_HAS_NO_LOCALIZATION)
|
||||||
|
# define TEST_HAS_NO_LOCALIZATION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TEST_STD_VER <= 17 || !defined(__cpp_char8_t)
|
||||||
|
# define TEST_HAS_NO_CHAR8_T
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_LIBCPP_HAS_NO_THREADS)
|
||||||
|
# define TEST_HAS_NO_THREADS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_LIBCPP_HAS_NO_FILESYSTEM)
|
||||||
|
# define TEST_HAS_NO_FILESYSTEM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_LIBCPP_HAS_NO_FGETPOS_FSETPOS)
|
||||||
|
# define TEST_HAS_NO_FGETPOS_FSETPOS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_LIBCPP_HAS_NO_C8RTOMB_MBRTOC8)
|
||||||
|
# define TEST_HAS_NO_C8RTOMB_MBRTOC8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_LIBCPP_HAS_NO_RANDOM_DEVICE)
|
||||||
|
# define TEST_HAS_NO_RANDOM_DEVICE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(TEST_COMPILER_CLANG)
|
||||||
|
# define TEST_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
|
||||||
|
# define TEST_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
|
||||||
|
# define TEST_CLANG_DIAGNOSTIC_IGNORED(str) _Pragma(TEST_STRINGIZE(clang diagnostic ignored str))
|
||||||
|
# define TEST_GCC_DIAGNOSTIC_IGNORED(str)
|
||||||
|
# define TEST_MSVC_DIAGNOSTIC_IGNORED(num)
|
||||||
|
#elif defined(TEST_COMPILER_GCC)
|
||||||
|
# define TEST_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
|
||||||
|
# define TEST_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
|
||||||
|
# define TEST_CLANG_DIAGNOSTIC_IGNORED(str)
|
||||||
|
# define TEST_GCC_DIAGNOSTIC_IGNORED(str) _Pragma(TEST_STRINGIZE(GCC diagnostic ignored str))
|
||||||
|
# define TEST_MSVC_DIAGNOSTIC_IGNORED(num)
|
||||||
|
#elif defined(TEST_COMPILER_MSVC)
|
||||||
|
# define TEST_DIAGNOSTIC_PUSH _Pragma("warning(push)")
|
||||||
|
# define TEST_DIAGNOSTIC_POP _Pragma("warning(pop)")
|
||||||
|
# define TEST_CLANG_DIAGNOSTIC_IGNORED(str)
|
||||||
|
# define TEST_GCC_DIAGNOSTIC_IGNORED(str)
|
||||||
|
# define TEST_MSVC_DIAGNOSTIC_IGNORED(num) _Pragma(TEST_STRINGIZE(warning(disable: num)))
|
||||||
|
#else
|
||||||
|
# define TEST_DIAGNOSTIC_PUSH
|
||||||
|
# define TEST_DIAGNOSTIC_POP
|
||||||
|
# define TEST_CLANG_DIAGNOSTIC_IGNORED(str)
|
||||||
|
# define TEST_GCC_DIAGNOSTIC_IGNORED(str)
|
||||||
|
# define TEST_MSVC_DIAGNOSTIC_IGNORED(num)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_cpp_attribute(msvc::no_unique_address)
|
||||||
|
#define TEST_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
|
||||||
|
#elif __has_cpp_attribute(no_unique_address)
|
||||||
|
#define TEST_NO_UNIQUE_ADDRESS [[no_unique_address]]
|
||||||
|
#else
|
||||||
|
#define TEST_NO_UNIQUE_ADDRESS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _LIBCPP_SHORT_WCHAR
|
||||||
|
# define TEST_SHORT_WCHAR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// This is a temporary workaround for user-defined `operator new` definitions
|
||||||
|
// not being picked up on Apple platforms in some circumstances. This is under
|
||||||
|
// investigation and should be short-lived.
|
||||||
|
#ifdef __APPLE__
|
||||||
|
# define TEST_WORKAROUND_BUG_109234844_WEAK __attribute__((weak))
|
||||||
|
#else
|
||||||
|
# define TEST_WORKAROUND_BUG_109234844_WEAK /* nothing */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SUPPORT_TEST_MACROS_HPP
|
179
third_party/libcxxabi/test/BUILD.mk
vendored
Normal file
179
third_party/libcxxabi/test/BUILD.mk
vendored
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||||
|
#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
|
||||||
|
|
||||||
|
ifeq ($(MODE), )
|
||||||
|
|
||||||
|
PKGS += THIRD_PARTY_LIBCXXABI_TEST
|
||||||
|
|
||||||
|
THIRD_PARTY_LIBCXXABI_TEST_A = o/$(MODE)/third_party/libcxxabi/test/test.a
|
||||||
|
|
||||||
|
THIRD_PARTY_LIBCXXABI_TEST_HDRS = \
|
||||||
|
third_party/libcxxabi/libcxx/test/support/make_test_thread.hh \
|
||||||
|
third_party/libcxxabi/libcxx/test/support/test_macros.hh \
|
||||||
|
third_party/libcxxabi/test/support/timer.hh
|
||||||
|
|
||||||
|
THIRD_PARTY_LIBCXXABI_TEST_SRCS = \
|
||||||
|
third_party/libcxxabi/test/catch_array_02.pass.cc \
|
||||||
|
third_party/libcxxabi/test/catch_class_01.pass.cc \
|
||||||
|
third_party/libcxxabi/test/catch_class_02.pass.cc \
|
||||||
|
third_party/libcxxabi/test/catch_class_03.pass.cc \
|
||||||
|
third_party/libcxxabi/test/catch_class_04.pass.cc \
|
||||||
|
third_party/libcxxabi/test/catch_const_pointer_nullptr.pass.cc \
|
||||||
|
third_party/libcxxabi/test/catch_function_02.pass.cc \
|
||||||
|
third_party/libcxxabi/test/catch_function_03.pass.cc \
|
||||||
|
third_party/libcxxabi/test/catch_in_noexcept.pass.cc \
|
||||||
|
third_party/libcxxabi/test/catch_member_data_pointer_01.pass.cc \
|
||||||
|
third_party/libcxxabi/test/catch_member_pointer_nullptr.pass.cc \
|
||||||
|
third_party/libcxxabi/test/catch_pointer_nullptr.pass.cc \
|
||||||
|
third_party/libcxxabi/test/catch_pointer_reference.pass.cc \
|
||||||
|
third_party/libcxxabi/test/catch_ptr.pass.cc \
|
||||||
|
third_party/libcxxabi/test/catch_ptr_02.pass.cc \
|
||||||
|
third_party/libcxxabi/test/catch_reference_nullptr.pass.cc \
|
||||||
|
third_party/libcxxabi/test/cxa_bad_cast.pass.cc \
|
||||||
|
third_party/libcxxabi/test/cxa_bad_typeid.pass.cc \
|
||||||
|
third_party/libcxxabi/test/cxa_thread_atexit_test.pass.cc \
|
||||||
|
third_party/libcxxabi/test/cxa_vec_new_overflow_PR41395.pass.cc \
|
||||||
|
third_party/libcxxabi/test/dynamic_cast.pass.cc \
|
||||||
|
third_party/libcxxabi/test/dynamic_cast3.pass.cc \
|
||||||
|
third_party/libcxxabi/test/dynamic_cast5.pass.cc \
|
||||||
|
third_party/libcxxabi/test/dynamic_cast14.pass.cc \
|
||||||
|
third_party/libcxxabi/test/dynamic_cast_stress.pass.cc \
|
||||||
|
third_party/libcxxabi/test/exception_object_alignment.pass.cc \
|
||||||
|
third_party/libcxxabi/test/exception_object_alignment.2.pass.cc \
|
||||||
|
third_party/libcxxabi/test/guard_test_basic.pass.cc \
|
||||||
|
third_party/libcxxabi/test/guard_threaded_test.pass.cc \
|
||||||
|
third_party/libcxxabi/test/incomplete_type.sh.cc \
|
||||||
|
third_party/libcxxabi/test/inherited_exception.pass.cc \
|
||||||
|
third_party/libcxxabi/test/test_aux_runtime.pass.cc \
|
||||||
|
third_party/libcxxabi/test/test_aux_runtime_op_array_new.pass.cc\
|
||||||
|
third_party/libcxxabi/test/test_demangle.pass.cc \
|
||||||
|
third_party/libcxxabi/test/test_exception_address_alignment.pass.cc \
|
||||||
|
third_party/libcxxabi/test/test_exception_storage.pass.cc \
|
||||||
|
third_party/libcxxabi/test/test_fallback_malloc.pass.cc \
|
||||||
|
third_party/libcxxabi/test/test_guard.pass.cc \
|
||||||
|
third_party/libcxxabi/test/test_vector1.pass.cc \
|
||||||
|
third_party/libcxxabi/test/test_vector2.pass.cc \
|
||||||
|
third_party/libcxxabi/test/test_vector3.pass.cc \
|
||||||
|
third_party/libcxxabi/test/uncaught_exception.pass.cc \
|
||||||
|
third_party/libcxxabi/test/uncaught_exceptions.pass.cc \
|
||||||
|
third_party/libcxxabi/test/unittest_demangle.pass.cc \
|
||||||
|
third_party/libcxxabi/test/unwind_01.pass.cc \
|
||||||
|
third_party/libcxxabi/test/unwind_02.pass.cc \
|
||||||
|
third_party/libcxxabi/test/unwind_03.pass.cc \
|
||||||
|
third_party/libcxxabi/test/unwind_04.pass.cc \
|
||||||
|
third_party/libcxxabi/test/unwind_05.pass.cc \
|
||||||
|
third_party/libcxxabi/test/unwind_06.pass.cc
|
||||||
|
|
||||||
|
# TODO: Add this test when #1073 is fixed
|
||||||
|
THIRD_PARTY_LIBCXXABI_TEST_SRCS_FAILING_COSMO = \
|
||||||
|
third_party/libcxxabi/test/thread_local_destruction_order.pass.cc
|
||||||
|
|
||||||
|
THIRD_PARTY_LIBCXXABI_TEST_SRCS_FAILING_GCC = \
|
||||||
|
third_party/libcxxabi/test/catch_array_01.pass.cc \
|
||||||
|
third_party/libcxxabi/test/catch_function_01.pass.cc \
|
||||||
|
third_party/libcxxabi/test/catch_member_function_pointer_01.pass.cc \
|
||||||
|
third_party/libcxxabi/test/catch_member_function_pointer_02.pass.cc
|
||||||
|
|
||||||
|
# Works if run, but fails to compile on GitHub Actions with an OOM
|
||||||
|
THIRD_PARTYLIBCXXABI_TEST_SRCS_COMPILE_OOM = \
|
||||||
|
third_party/libcxxabi/test/catch_multi_level_pointer.pass.cc
|
||||||
|
|
||||||
|
THIRD_PARTY_LIBCXXABI_TEST_COMS = \
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_SRCS:%.cc=o/$(MODE)/%.com)
|
||||||
|
|
||||||
|
THIRD_PARTY_LIBCXXABI_TEST_TESTS = \
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_COMS:%=%.ok)
|
||||||
|
|
||||||
|
THIRD_PARTY_LIBCXXABI_TEST_OBJS = \
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_SRCS:%.cc=o/$(MODE)/%.o) \
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/incomplete_type.sh.one.o \
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/incomplete_type.sh.two.o
|
||||||
|
|
||||||
|
THIRD_PARTY_LIBCXXABI_TEST_OBJS_WNO_EXCEPTIONS = \
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/catch_class_03.pass.o \
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/catch_class_04.pass.o \
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/catch_ptr.pass.o \
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/catch_ptr_02.pass.o \
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/inherited_exception.pass.o
|
||||||
|
|
||||||
|
THIRD_PARTY_LIBCXXABI_TEST_OBJS_CPP14 = \
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/unwind_02.pass.o \
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/unwind_03.pass.o \
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/unwind_04.pass.o \
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/unwind_05.pass.o
|
||||||
|
|
||||||
|
THIRD_PARTY_LIBCXXABI_TEST_BINS = \
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_COMS) \
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_COMS:%=%.dbg)
|
||||||
|
|
||||||
|
THIRD_PARTY_LIBCXXABI_TEST_CHECKS = \
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_COMS:%=%.runs) \
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_HDRS:%=o/$(MODE)/%.ok)
|
||||||
|
|
||||||
|
THIRD_PARTY_LIBCXXABI_TEST_DIRECTDEPS = \
|
||||||
|
LIBC_NEXGEN32E \
|
||||||
|
THIRD_PARTY_LIBCXX \
|
||||||
|
THIRD_PARTY_LIBCXXABI
|
||||||
|
|
||||||
|
THIRD_PARTY_LIBCXXABI_TEST_DEPS := \
|
||||||
|
$(call uniq,$(foreach x,$(THIRD_PARTY_LIBCXXABI_TEST_DIRECTDEPS),$($(x))))
|
||||||
|
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_A): \
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_A).pkg
|
||||||
|
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_A).pkg: \
|
||||||
|
$(foreach x,$(THIRD_PARTY_LIBCXXABI_TEST_DIRECTDEPS),$($(x)_A).pkg)
|
||||||
|
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/%.com.dbg: \
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_DEPS) \
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_A) \
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/%.o \
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_A).pkg \
|
||||||
|
$(CRT) \
|
||||||
|
$(APE_NO_MODIFY_SELF)
|
||||||
|
@$(APELINK)
|
||||||
|
|
||||||
|
# TODO: Remove constinit hacks when we have C++20
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_OBJS): private \
|
||||||
|
CXXFLAGS += \
|
||||||
|
-fexceptions \
|
||||||
|
-frtti \
|
||||||
|
-D_LIBCXXABI_BUILDING_LIBRARY \
|
||||||
|
-D_LIBCPP_BUILDING_LIBRARY \
|
||||||
|
-D_LIBCPP_CONSTINIT=__constinit
|
||||||
|
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_OBJS_WNO_EXCEPTIONS): private \
|
||||||
|
CXXFLAGS += \
|
||||||
|
-Wno-exceptions
|
||||||
|
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_OBJS_CPP14): private \
|
||||||
|
CXXFLAGS += \
|
||||||
|
-std=gnu++14
|
||||||
|
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/guard_test_basic.pass.o: private \
|
||||||
|
CXXFLAGS += \
|
||||||
|
-Wno-invalid-memory-model
|
||||||
|
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/incomplete_type.sh.one.o: private \
|
||||||
|
CXXFLAGS += \
|
||||||
|
-Wno-unreachable-code
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/incomplete_type.sh.two.o: private \
|
||||||
|
CXXFLAGS += \
|
||||||
|
-Wno-unreachable-code \
|
||||||
|
-DTU_ONE
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/incomplete_type.sh.com.dbg: \
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_DEPS) \
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_A) \
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/incomplete_type.sh.one.o \
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test/incomplete_type.sh.two.o \
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_A).pkg \
|
||||||
|
$(CRT) \
|
||||||
|
$(APE_NO_MODIFY_SELF)
|
||||||
|
@$(APELINK)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: o/$(MODE)/third_party/libcxxabi/test
|
||||||
|
o/$(MODE)/third_party/libcxxabi/test: \
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_BINS) \
|
||||||
|
$(THIRD_PARTY_LIBCXXABI_TEST_CHECKS)
|
36
third_party/libcxxabi/test/catch_array_01.pass.cc
vendored
Normal file
36
third_party/libcxxabi/test/catch_array_01.pass.cc
vendored
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// Can you have a catch clause of array type that catches anything?
|
||||||
|
|
||||||
|
// GCC incorrectly allows array types to be caught by reference.
|
||||||
|
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69372
|
||||||
|
// XFAIL: gcc
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
typedef char Array[4];
|
||||||
|
Array a = {'H', 'i', '!', 0};
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw a; // converts to char*
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (Array& b) // can't catch char*
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
32
third_party/libcxxabi/test/catch_array_02.pass.cc
vendored
Normal file
32
third_party/libcxxabi/test/catch_array_02.pass.cc
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// Can you have a catch clause of array type that catches anything?
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
typedef char Array[4];
|
||||||
|
Array a = {'H', 'i', '!', 0};
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw a; // converts to char*
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (Array b) // equivalent to char*
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
61
third_party/libcxxabi/test/catch_class_01.pass.cc
vendored
Normal file
61
third_party/libcxxabi/test/catch_class_01.pass.cc
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
struct A
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
explicit A(int id) : id_(id) {count++;}
|
||||||
|
A(const A& a) : id_(a.id_) {count++;}
|
||||||
|
~A() {count--;}
|
||||||
|
};
|
||||||
|
|
||||||
|
int A::count = 0;
|
||||||
|
|
||||||
|
void f1()
|
||||||
|
{
|
||||||
|
throw A(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void f2()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
assert(A::count == 0);
|
||||||
|
f1();
|
||||||
|
}
|
||||||
|
catch (A a)
|
||||||
|
{
|
||||||
|
assert(A::count != 0);
|
||||||
|
assert(a.id_ == 3);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f2();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const A& a)
|
||||||
|
{
|
||||||
|
assert(A::count != 0);
|
||||||
|
assert(a.id_ == 3);
|
||||||
|
}
|
||||||
|
assert(A::count == 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
86
third_party/libcxxabi/test/catch_class_02.pass.cc
vendored
Normal file
86
third_party/libcxxabi/test/catch_class_02.pass.cc
vendored
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
#include "third_party/libcxx/exception"
|
||||||
|
#include "libc/isystem/stdlib.h"
|
||||||
|
#include "libc/isystem/assert.h"
|
||||||
|
|
||||||
|
struct B
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
explicit B(int id) : id_(id) {count++;}
|
||||||
|
B(const B& a) : id_(a.id_) {count++;}
|
||||||
|
~B() {count--;}
|
||||||
|
};
|
||||||
|
|
||||||
|
int B::count = 0;
|
||||||
|
|
||||||
|
struct A
|
||||||
|
: B
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
explicit A(int id) : B(id-1), id_(id) {count++;}
|
||||||
|
A(const A& a) : B(a.id_-1), id_(a.id_) {count++;}
|
||||||
|
~A() {count--;}
|
||||||
|
};
|
||||||
|
|
||||||
|
int A::count = 0;
|
||||||
|
|
||||||
|
void f1()
|
||||||
|
{
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
A a(3);
|
||||||
|
assert(A::count == 1);
|
||||||
|
assert(B::count == 1);
|
||||||
|
throw a;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void f2()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
assert(A::count == 0);
|
||||||
|
f1();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (A a)
|
||||||
|
{
|
||||||
|
assert(A::count != 0);
|
||||||
|
assert(B::count != 0);
|
||||||
|
assert(a.id_ == 3);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (B b)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f2();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const B& b)
|
||||||
|
{
|
||||||
|
assert(B::count != 0);
|
||||||
|
assert(b.id_ == 2);
|
||||||
|
}
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
198
third_party/libcxxabi/test/catch_class_03.pass.cc
vendored
Normal file
198
third_party/libcxxabi/test/catch_class_03.pass.cc
vendored
Normal file
|
@ -0,0 +1,198 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
/*
|
||||||
|
This test checks that adjustedPtr is correct as there exist offsets in this
|
||||||
|
object for the various subobjects, all of which have a unique id_ to
|
||||||
|
check against.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
// Compilers emit warnings about exceptions of type 'Child' being caught by
|
||||||
|
// an earlier handler of type 'Base'. Congrats, you've just diagnosed the
|
||||||
|
// behavior under test.
|
||||||
|
// ADDITIONAL_COMPILE_FLAGS: -Wno-exceptions
|
||||||
|
|
||||||
|
#include "third_party/libcxx/exception"
|
||||||
|
#include "libc/isystem/stdlib.h"
|
||||||
|
#include "libc/isystem/assert.h"
|
||||||
|
|
||||||
|
struct B
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
explicit B(int id) : id_(id) {count++;}
|
||||||
|
B(const B& a) : id_(a.id_) {count++;}
|
||||||
|
~B() {count--;}
|
||||||
|
};
|
||||||
|
|
||||||
|
int B::count = 0;
|
||||||
|
|
||||||
|
struct C1
|
||||||
|
: B
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
explicit C1(int id) : B(id-2), id_(id) {count++;}
|
||||||
|
C1(const C1& a) : B(a.id_-2), id_(a.id_) {count++;}
|
||||||
|
~C1() {count--;}
|
||||||
|
};
|
||||||
|
|
||||||
|
int C1::count = 0;
|
||||||
|
|
||||||
|
struct C2
|
||||||
|
: B
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
explicit C2(int id) : B(id-2), id_(id) {count++;}
|
||||||
|
C2(const C2& a) : B(a.id_-2), id_(a.id_) {count++;}
|
||||||
|
~C2() {count--;}
|
||||||
|
};
|
||||||
|
|
||||||
|
int C2::count = 0;
|
||||||
|
|
||||||
|
struct A
|
||||||
|
: C1, C2
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
explicit A(int id) : C1(id-1), C2(id-2), id_(id) {count++;}
|
||||||
|
A(const A& a) : C1(a.id_-1), C2(a.id_-2), id_(a.id_) {count++;}
|
||||||
|
~A() {count--;}
|
||||||
|
};
|
||||||
|
|
||||||
|
int A::count = 0;
|
||||||
|
|
||||||
|
void f1()
|
||||||
|
{
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(C1::count == 0);
|
||||||
|
assert(C2::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
A a(5);
|
||||||
|
assert(A::count == 1);
|
||||||
|
assert(C1::count == 1);
|
||||||
|
assert(C2::count == 1);
|
||||||
|
assert(B::count == 2);
|
||||||
|
|
||||||
|
assert(a.id_ == 5);
|
||||||
|
assert(static_cast<C1&>(a).id_ == 4);
|
||||||
|
assert(static_cast<C2&>(a).id_ == 3);
|
||||||
|
assert(static_cast<B&>(static_cast<C1&>(a)).id_ == 2);
|
||||||
|
assert(static_cast<B&>(static_cast<C2&>(a)).id_ == 1);
|
||||||
|
throw a;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void f2()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(C1::count == 0);
|
||||||
|
assert(C2::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
f1();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const A& a) // can catch A
|
||||||
|
{
|
||||||
|
assert(a.id_ == 5);
|
||||||
|
assert(static_cast<const C1&>(a).id_ == 4);
|
||||||
|
assert(static_cast<const C2&>(a).id_ == 3);
|
||||||
|
assert(static_cast<const B&>(static_cast<const C1&>(a)).id_ == 2);
|
||||||
|
assert(static_cast<const B&>(static_cast<const C2&>(a)).id_ == 1);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (const C1&)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const C2&)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const B&)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void f3()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(C1::count == 0);
|
||||||
|
assert(C2::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
f2();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const B& a) // can not catch B (ambiguous base)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const C1& c1) // can catch C1
|
||||||
|
{
|
||||||
|
assert(c1.id_ == 4);
|
||||||
|
assert(static_cast<const B&>(c1).id_ == 2);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (const C2&)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void f4()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(C1::count == 0);
|
||||||
|
assert(C2::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
f3();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const B& a) // can not catch B (ambiguous base)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const C2& c2) // can catch C2
|
||||||
|
{
|
||||||
|
assert(c2.id_ == 3);
|
||||||
|
assert(static_cast<const B&>(c2).id_ == 1);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (const C1&)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f4();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(C1::count == 0);
|
||||||
|
assert(C2::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
221
third_party/libcxxabi/test/catch_class_04.pass.cc
vendored
Normal file
221
third_party/libcxxabi/test/catch_class_04.pass.cc
vendored
Normal file
|
@ -0,0 +1,221 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
/*
|
||||||
|
This test checks that adjustedPtr is correct as there exist offsets in this
|
||||||
|
object for the various subobjects, all of which have a unique id_ to
|
||||||
|
check against. It also checks that virtual bases work properly
|
||||||
|
*/
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
// Compilers emit warnings about exceptions of type 'Child' being caught by
|
||||||
|
// an earlier handler of type 'Base'. Congrats, you've just diagnosed the
|
||||||
|
// behavior under test.
|
||||||
|
// ADDITIONAL_COMPILE_FLAGS: -Wno-exceptions
|
||||||
|
|
||||||
|
#include "third_party/libcxx/exception"
|
||||||
|
#include "libc/isystem/stdlib.h"
|
||||||
|
#include "libc/isystem/assert.h"
|
||||||
|
|
||||||
|
struct B
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
explicit B(int id) : id_(id) {count++;}
|
||||||
|
B(const B& a) : id_(a.id_) {count++;}
|
||||||
|
~B() {count--;}
|
||||||
|
};
|
||||||
|
|
||||||
|
int B::count = 0;
|
||||||
|
|
||||||
|
struct C1
|
||||||
|
: virtual B
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
explicit C1(int id) : B(id-2), id_(id) {count++;}
|
||||||
|
C1(const C1& a) : B(a.id_-2), id_(a.id_) {count++;}
|
||||||
|
~C1() {count--;}
|
||||||
|
};
|
||||||
|
|
||||||
|
int C1::count = 0;
|
||||||
|
|
||||||
|
struct C2
|
||||||
|
: virtual private B
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
explicit C2(int id) : B(id-2), id_(id) {count++;}
|
||||||
|
C2(const C2& a) : B(a.id_-2), id_(a.id_) {count++;}
|
||||||
|
~C2() {count--;}
|
||||||
|
};
|
||||||
|
|
||||||
|
int C2::count = 0;
|
||||||
|
|
||||||
|
struct A
|
||||||
|
: C1, C2
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
explicit A(int id) : B(id+3), C1(id-1), C2(id-2), id_(id) {count++;}
|
||||||
|
A(const A& a) : B(a.id_+3), C1(a.id_-1), C2(a.id_-2), id_(a.id_) {count++;}
|
||||||
|
~A() {count--;}
|
||||||
|
};
|
||||||
|
|
||||||
|
int A::count = 0;
|
||||||
|
|
||||||
|
void f1()
|
||||||
|
{
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(C1::count == 0);
|
||||||
|
assert(C2::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
A a(5);
|
||||||
|
assert(A::count == 1);
|
||||||
|
assert(C1::count == 1);
|
||||||
|
assert(C2::count == 1);
|
||||||
|
assert(B::count == 1);
|
||||||
|
|
||||||
|
assert(a.id_ == 5);
|
||||||
|
assert(static_cast<C1&>(a).id_ == 4);
|
||||||
|
assert(static_cast<C2&>(a).id_ == 3);
|
||||||
|
assert(static_cast<B&>(a).id_ == 8);
|
||||||
|
throw a;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void f2()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(C1::count == 0);
|
||||||
|
assert(C2::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
f1();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const A& a) // can catch A
|
||||||
|
{
|
||||||
|
assert(a.id_ == 5);
|
||||||
|
assert(static_cast<const C1&>(a).id_ == 4);
|
||||||
|
assert(static_cast<const C2&>(a).id_ == 3);
|
||||||
|
assert(static_cast<const B&>(a).id_ == 8);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (const C1&)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const C2&)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const B&)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void f3()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(C1::count == 0);
|
||||||
|
assert(C2::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
f2();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const B& a) // can catch B
|
||||||
|
{
|
||||||
|
assert(static_cast<const B&>(a).id_ == 8);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (const C1& c1)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const C2&)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void f4()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(C1::count == 0);
|
||||||
|
assert(C2::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
f3();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const C2& c2) // can catch C2
|
||||||
|
{
|
||||||
|
assert(c2.id_ == 3);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (const B& a) // can not catch B (ambiguous base)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const C1&)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void f5()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(C1::count == 0);
|
||||||
|
assert(C2::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
f4();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const C1& c1) // can catch C1
|
||||||
|
{
|
||||||
|
assert(c1.id_ == 4);
|
||||||
|
assert(static_cast<const B&>(c1).id_ == 8);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (const B& a)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const C2&)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f5();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(C1::count == 0);
|
||||||
|
assert(C2::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
148
third_party/libcxxabi/test/catch_const_pointer_nullptr.pass.cc
vendored
Normal file
148
third_party/libcxxabi/test/catch_const_pointer_nullptr.pass.cc
vendored
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
|
||||||
|
// Clang emits warnings about exceptions of type 'Child' being caught by
|
||||||
|
// an earlier handler of type 'Base'. Congrats clang, you've just
|
||||||
|
// diagnosed the behavior under test.
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic ignored "-Wexceptions"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_feature(cxx_nullptr)
|
||||||
|
|
||||||
|
struct A {};
|
||||||
|
|
||||||
|
void test1()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw nullptr;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (A* p)
|
||||||
|
{
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch (const A*)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test2()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw nullptr;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const A* p)
|
||||||
|
{
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch (A*)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test3()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw nullptr;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const A* const p)
|
||||||
|
{
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch (A*)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test4()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw nullptr;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (A* p)
|
||||||
|
{
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch (const A* const)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test5()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw nullptr;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (A const* p)
|
||||||
|
{
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch (A*)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test6()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw nullptr;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (A* p)
|
||||||
|
{
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch (A const*)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void test1() {}
|
||||||
|
void test2() {}
|
||||||
|
void test3() {}
|
||||||
|
void test4() {}
|
||||||
|
void test5() {}
|
||||||
|
void test6() {}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
test1();
|
||||||
|
test2();
|
||||||
|
test3();
|
||||||
|
test4();
|
||||||
|
test5();
|
||||||
|
test6();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
56
third_party/libcxxabi/test/catch_function_01.pass.cc
vendored
Normal file
56
third_party/libcxxabi/test/catch_function_01.pass.cc
vendored
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// Can you have a catch clause of array type that catches anything?
|
||||||
|
|
||||||
|
// GCC incorrectly allows function pointer to be caught by reference.
|
||||||
|
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69372
|
||||||
|
// XFAIL: gcc
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
// 65ace9daa360 made it in the dylib in macOS 10.11
|
||||||
|
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{9|10}}
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
|
||||||
|
template <class Tp>
|
||||||
|
bool can_convert(Tp) { return true; }
|
||||||
|
|
||||||
|
template <class>
|
||||||
|
bool can_convert(...) { return false; }
|
||||||
|
|
||||||
|
void f() {}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
typedef void Function();
|
||||||
|
assert(!can_convert<Function&>(&f));
|
||||||
|
assert(!can_convert<void*>(&f));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw f; // converts to void (*)()
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (Function& b) // can't catch void (*)()
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (void*) // can't catch as void*
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch(Function*)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
33
third_party/libcxxabi/test/catch_function_02.pass.cc
vendored
Normal file
33
third_party/libcxxabi/test/catch_function_02.pass.cc
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// Can you have a catch clause of array type that catches anything?
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
|
||||||
|
void f() {}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
typedef void Function();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw f; // converts to void (*)()
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (Function b) // equivalent to void (*)()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
69
third_party/libcxxabi/test/catch_function_03.pass.cc
vendored
Normal file
69
third_party/libcxxabi/test/catch_function_03.pass.cc
vendored
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// Can a noexcept function pointer be caught by a non-noexcept catch clause?
|
||||||
|
// UNSUPPORTED: c++03, c++11, c++14
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
// Support for catching a function pointer including noexcept was shipped in macOS 10.13
|
||||||
|
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{9|10|11|12}}
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
|
||||||
|
template<bool Noexcept> void f() noexcept(Noexcept) {}
|
||||||
|
template<bool Noexcept> using FnType = void() noexcept(Noexcept);
|
||||||
|
|
||||||
|
template<bool ThrowNoexcept, bool CatchNoexcept>
|
||||||
|
void check()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto *p = f<ThrowNoexcept>;
|
||||||
|
throw p;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (FnType<CatchNoexcept> *p)
|
||||||
|
{
|
||||||
|
assert(ThrowNoexcept || !CatchNoexcept);
|
||||||
|
assert(p == &f<ThrowNoexcept>);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(!ThrowNoexcept && CatchNoexcept);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_deep() {
|
||||||
|
auto *p = f<true>;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw &p;
|
||||||
|
}
|
||||||
|
catch (FnType<false> **q)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (FnType<true> **q)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
check<false, false>();
|
||||||
|
check<false, true>();
|
||||||
|
check<true, false>();
|
||||||
|
check<true, true>();
|
||||||
|
check_deep();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
38
third_party/libcxxabi/test/catch_in_noexcept.pass.cc
vendored
Normal file
38
third_party/libcxxabi/test/catch_in_noexcept.pass.cc
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
//===---------------------- catch_in_noexcept.cpp--------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++03
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
#include "third_party/libcxx/exception"
|
||||||
|
#include "libc/isystem/stdlib.h"
|
||||||
|
#include "libc/isystem/assert.h"
|
||||||
|
|
||||||
|
struct A {};
|
||||||
|
|
||||||
|
// Despite being marked as noexcept, this function must have an EHT entry that
|
||||||
|
// is not 'cantunwind', so that the unwinder can correctly deal with the throw.
|
||||||
|
void f1() noexcept
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
A a;
|
||||||
|
throw a;
|
||||||
|
assert(false);
|
||||||
|
} catch (...) {
|
||||||
|
assert(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
f1();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
179
third_party/libcxxabi/test/catch_member_data_pointer_01.pass.cc
vendored
Normal file
179
third_party/libcxxabi/test/catch_member_data_pointer_01.pass.cc
vendored
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
// 1b00fc5d8133 made it in the dylib in macOS 10.11
|
||||||
|
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{9|10}}
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
|
||||||
|
struct A
|
||||||
|
{
|
||||||
|
A() : i(0), j(0) {} // explicitly initialize 'i' to prevent warnings
|
||||||
|
const int i;
|
||||||
|
int j;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef const int A::*md1;
|
||||||
|
typedef int A::*md2;
|
||||||
|
|
||||||
|
struct B : public A
|
||||||
|
{
|
||||||
|
B() : k(0), l(0) {} // explicitly initialize 'k' to prevent warnings.
|
||||||
|
const int k;
|
||||||
|
int l;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef const int B::*der1;
|
||||||
|
typedef int B::*der2;
|
||||||
|
|
||||||
|
void test1()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw &A::i;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (md2)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (md1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that cv qualified conversions are allowed.
|
||||||
|
void test2()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw &A::j;
|
||||||
|
}
|
||||||
|
catch (md2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw &A::j;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (md1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that Base -> Derived conversions are NOT allowed.
|
||||||
|
void test3()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw &A::i;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (md2)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (der2)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (der1)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (md1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that Base -> Derived conversions NOT are allowed with different cv
|
||||||
|
// qualifiers.
|
||||||
|
void test4()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw &A::j;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (der2)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (der1)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (md2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that no Derived -> Base conversions are allowed.
|
||||||
|
void test5()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw &B::k;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (md1)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (md2)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (der1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw &B::l;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (md1)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (md2)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (der2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
test1();
|
||||||
|
test2();
|
||||||
|
test3();
|
||||||
|
test4();
|
||||||
|
test5();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
172
third_party/libcxxabi/test/catch_member_function_pointer_01.pass.cc
vendored
Normal file
172
third_party/libcxxabi/test/catch_member_function_pointer_01.pass.cc
vendored
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// GCC incorrectly allows PMF type "void (T::*)()" to be caught as "void (T::*)() const"
|
||||||
|
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69375
|
||||||
|
// XFAIL: gcc
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
|
||||||
|
struct A
|
||||||
|
{
|
||||||
|
void foo() {}
|
||||||
|
void bar() const {}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (A::*mf1)();
|
||||||
|
typedef void (A::*mf2)() const;
|
||||||
|
|
||||||
|
struct B : public A
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (B::*dmf1)();
|
||||||
|
typedef void (B::*dmf2)() const;
|
||||||
|
|
||||||
|
template <class Tp>
|
||||||
|
bool can_convert(Tp) { return true; }
|
||||||
|
|
||||||
|
template <class>
|
||||||
|
bool can_convert(...) { return false; }
|
||||||
|
|
||||||
|
|
||||||
|
void test1()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw &A::foo;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (mf2)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (mf1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test2()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw &A::bar;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (mf1)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (mf2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_derived()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw (mf1)0;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (dmf2)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (dmf1)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (mf1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw (mf2)0;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (dmf1)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (dmf2)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (mf2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(!can_convert<mf1>((dmf1)0));
|
||||||
|
assert(!can_convert<mf2>((dmf1)0));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw (dmf1)0;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (mf2)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (mf1)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(!can_convert<mf1>((dmf2)0));
|
||||||
|
assert(!can_convert<mf2>((dmf2)0));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw (dmf2)0;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (mf2)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (mf1)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_void()
|
||||||
|
{
|
||||||
|
assert(!can_convert<void*>(&A::foo));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw &A::foo;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (void*)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
test1();
|
||||||
|
test2();
|
||||||
|
test_derived();
|
||||||
|
test_void();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
75
third_party/libcxxabi/test/catch_member_function_pointer_02.pass.cc
vendored
Normal file
75
third_party/libcxxabi/test/catch_member_function_pointer_02.pass.cc
vendored
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// Can a noexcept member function pointer be caught by a non-noexcept catch clause?
|
||||||
|
// UNSUPPORTED: c++03, c++11, c++14
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
// Support for catching a function pointer including noexcept was shipped in macOS 10.13
|
||||||
|
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{9|10|11|12}}
|
||||||
|
|
||||||
|
// GCC supports noexcept function types but this test still fails.
|
||||||
|
// This is likely a bug in their implementation. Investigation needed.
|
||||||
|
// XFAIL: gcc-11, gcc-12, gcc-13
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
|
||||||
|
struct X {
|
||||||
|
template<bool Noexcept> void f() noexcept(Noexcept) {}
|
||||||
|
};
|
||||||
|
template<bool Noexcept> using FnType = void (X::*)() noexcept(Noexcept);
|
||||||
|
|
||||||
|
template<bool ThrowNoexcept, bool CatchNoexcept>
|
||||||
|
void check()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto p = &X::f<ThrowNoexcept>;
|
||||||
|
throw p;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (FnType<CatchNoexcept> p)
|
||||||
|
{
|
||||||
|
assert(ThrowNoexcept || !CatchNoexcept);
|
||||||
|
assert(p == &X::f<ThrowNoexcept>);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(!ThrowNoexcept && CatchNoexcept);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_deep() {
|
||||||
|
FnType<true> p = &X::f<true>;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw &p;
|
||||||
|
}
|
||||||
|
catch (FnType<false> *q)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (FnType<true> *q)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
check<false, false>();
|
||||||
|
check<false, true>();
|
||||||
|
check<true, false>();
|
||||||
|
check<true, true>();
|
||||||
|
check_deep();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
80
third_party/libcxxabi/test/catch_member_pointer_nullptr.pass.cc
vendored
Normal file
80
third_party/libcxxabi/test/catch_member_pointer_nullptr.pass.cc
vendored
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// Catching an exception thrown as nullptr was not properly handled before
|
||||||
|
// 2f984cab4fa7, which landed in macOS 10.13
|
||||||
|
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{9|10|11|12}}
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
|
||||||
|
#if __has_feature(cxx_nullptr)
|
||||||
|
|
||||||
|
struct A
|
||||||
|
{
|
||||||
|
const int i;
|
||||||
|
int j;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef const int A::*md1;
|
||||||
|
typedef int A::*md2;
|
||||||
|
|
||||||
|
void test1()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw nullptr;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (md2 p)
|
||||||
|
{
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch (md1)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test2()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw nullptr;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (md1 p)
|
||||||
|
{
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch (md2)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void test1()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void test2()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
test1();
|
||||||
|
test2();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
149
third_party/libcxxabi/test/catch_multi_level_pointer.pass.cc
vendored
Normal file
149
third_party/libcxxabi/test/catch_multi_level_pointer.pass.cc
vendored
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
// 1b00fc5d8133 made it in the dylib in macOS 10.11
|
||||||
|
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{9|10}}
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
#include "third_party/libcxx/cstdio"
|
||||||
|
#include "third_party/libcxx/cstdlib"
|
||||||
|
|
||||||
|
// Roll our own assertion macro to get better error messages out of the tests.
|
||||||
|
// In particular on systems that don't use __PRETTY_FUNCTION__ in assertions.
|
||||||
|
#define my_assert(pred, msg) do_assert(pred, msg, __LINE__, __PRETTY_FUNCTION__)
|
||||||
|
|
||||||
|
void do_assert(bool assert_passed, const char* msg, int line, const char* func) {
|
||||||
|
if (assert_passed)
|
||||||
|
return;
|
||||||
|
std::printf("%s:%d %s: Assertion Failed '%s'\n\n", __FILE__, line, func, msg);
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct A {};
|
||||||
|
struct Base {};
|
||||||
|
struct Derived : public Base {};
|
||||||
|
|
||||||
|
template <class To>
|
||||||
|
bool test_conversion(To) { return true; }
|
||||||
|
|
||||||
|
template <class To>
|
||||||
|
bool test_conversion(...) { return false; }
|
||||||
|
|
||||||
|
template <class Pointer>
|
||||||
|
struct CreatePointer {
|
||||||
|
Pointer operator()() const {
|
||||||
|
return (Pointer)0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Tp>
|
||||||
|
struct CreatePointer<Tp*> {
|
||||||
|
Tp* operator()() const {
|
||||||
|
return (Tp*)42;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Throw, class Catch>
|
||||||
|
void catch_pointer_test() {
|
||||||
|
Throw throw_ptr = CreatePointer<Throw>()();
|
||||||
|
// Use the compiler to determine if the exception of type Throw can be
|
||||||
|
// implicitly converted to type Catch.
|
||||||
|
const bool can_convert = test_conversion<Catch>(throw_ptr);
|
||||||
|
try {
|
||||||
|
throw throw_ptr;
|
||||||
|
assert(false);
|
||||||
|
} catch (Catch catch_ptr) {
|
||||||
|
Catch catch2 = CreatePointer<Catch>()();
|
||||||
|
my_assert(can_convert, "non-convertible type incorrectly caught");
|
||||||
|
my_assert(catch_ptr == catch2,
|
||||||
|
"Thrown pointer does not match caught ptr");
|
||||||
|
} catch (...) {
|
||||||
|
my_assert(!can_convert, "convertible type incorrectly not caught");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate CV qualified pointer typedefs.
|
||||||
|
template <class Tp, bool First = false>
|
||||||
|
struct TestTypes {
|
||||||
|
typedef Tp* Type;
|
||||||
|
typedef Tp const* CType;
|
||||||
|
typedef Tp volatile* VType;
|
||||||
|
typedef Tp const volatile* CVType;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Special case for cv-qualifying a pointer-to-member without adding an extra
|
||||||
|
// pointer to it.
|
||||||
|
template <class Member, class Class>
|
||||||
|
struct TestTypes<Member Class::*, true> {
|
||||||
|
typedef Member (Class::*Type);
|
||||||
|
typedef const Member (Class::*CType);
|
||||||
|
typedef volatile Member (Class::*VType);
|
||||||
|
typedef const volatile Member (Class::*CVType);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Throw, class Catch, int level, bool first = false>
|
||||||
|
struct generate_tests_imp {
|
||||||
|
typedef TestTypes<Throw, first> ThrowTypes;
|
||||||
|
typedef TestTypes<Catch, first> CatchTypes;
|
||||||
|
void operator()() {
|
||||||
|
typedef typename ThrowTypes::Type Type;
|
||||||
|
typedef typename ThrowTypes::CType CType;
|
||||||
|
typedef typename ThrowTypes::VType VType;
|
||||||
|
typedef typename ThrowTypes::CVType CVType;
|
||||||
|
|
||||||
|
run_catch_tests<Type>();
|
||||||
|
run_catch_tests<CType>();
|
||||||
|
run_catch_tests<VType>();
|
||||||
|
run_catch_tests<CVType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ThrowTp>
|
||||||
|
void run_catch_tests() {
|
||||||
|
typedef typename CatchTypes::Type Type;
|
||||||
|
typedef typename CatchTypes::CType CType;
|
||||||
|
typedef typename CatchTypes::VType VType;
|
||||||
|
typedef typename CatchTypes::CVType CVType;
|
||||||
|
|
||||||
|
catch_pointer_test<ThrowTp, Type>();
|
||||||
|
catch_pointer_test<ThrowTp, CType>();
|
||||||
|
catch_pointer_test<ThrowTp, VType>();
|
||||||
|
catch_pointer_test<ThrowTp, CVType>();
|
||||||
|
|
||||||
|
generate_tests_imp<ThrowTp, Type, level-1>()();
|
||||||
|
generate_tests_imp<ThrowTp, CType, level-1>()();
|
||||||
|
generate_tests_imp<ThrowTp, VType, level-1>()();
|
||||||
|
generate_tests_imp<ThrowTp, CVType, level-1>()();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Throw, class Catch, bool first>
|
||||||
|
struct generate_tests_imp<Throw, Catch, 0, first> {
|
||||||
|
void operator()() {
|
||||||
|
catch_pointer_test<Throw, Catch>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Throw, class Catch, int level>
|
||||||
|
struct generate_tests : generate_tests_imp<Throw, Catch, level, true> {};
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
generate_tests<int, int, 3>()();
|
||||||
|
generate_tests<Base, Derived, 2>()();
|
||||||
|
generate_tests<Derived, Base, 2>()();
|
||||||
|
generate_tests<int, void, 2>()();
|
||||||
|
generate_tests<void, int, 2>()();
|
||||||
|
|
||||||
|
generate_tests<int A::*, int A::*, 3>()();
|
||||||
|
generate_tests<int A::*, void, 2>()();
|
||||||
|
generate_tests<void, int A::*, 2>()();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
81
third_party/libcxxabi/test/catch_pointer_nullptr.pass.cc
vendored
Normal file
81
third_party/libcxxabi/test/catch_pointer_nullptr.pass.cc
vendored
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// Catching an exception thrown as nullptr was not properly handled before
|
||||||
|
// 2f984cab4fa7, which landed in macOS 10.13
|
||||||
|
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{9|10|11|12}}
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++03
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
#include "third_party/libcxx/cstdlib"
|
||||||
|
|
||||||
|
struct A {};
|
||||||
|
|
||||||
|
void test1()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw nullptr;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (int* p)
|
||||||
|
{
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch (long*)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test2()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw nullptr;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (A* p)
|
||||||
|
{
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch (int*)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Catch>
|
||||||
|
void catch_nullptr_test() {
|
||||||
|
try {
|
||||||
|
throw nullptr;
|
||||||
|
assert(false);
|
||||||
|
} catch (Catch c) {
|
||||||
|
assert(!c);
|
||||||
|
} catch (...) {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
// catch naked nullptrs
|
||||||
|
test1();
|
||||||
|
test2();
|
||||||
|
|
||||||
|
catch_nullptr_test<int*>();
|
||||||
|
catch_nullptr_test<int**>();
|
||||||
|
catch_nullptr_test<int A::*>();
|
||||||
|
catch_nullptr_test<const int A::*>();
|
||||||
|
catch_nullptr_test<int A::**>();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
447
third_party/libcxxabi/test/catch_pointer_reference.pass.cc
vendored
Normal file
447
third_party/libcxxabi/test/catch_pointer_reference.pass.cc
vendored
Normal file
|
@ -0,0 +1,447 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This test case checks specifically the cases under bullet 3.1 & 3.2:
|
||||||
|
//
|
||||||
|
// C++ ABI 15.3:
|
||||||
|
// A handler is a match for an exception object of type E if
|
||||||
|
// * The handler is of type cv T or cv T& and E and T are the same type
|
||||||
|
// (ignoring the top-level cv-qualifiers), or
|
||||||
|
// * the handler is of type cv T or cv T& and T is an unambiguous base
|
||||||
|
// class of E, or
|
||||||
|
// > * the handler is of type cv1 T* cv2 and E is a pointer type that can <
|
||||||
|
// > be converted to the type of the handler by either or both of <
|
||||||
|
// > o a standard pointer conversion (4.10 [conv.ptr]) not involving <
|
||||||
|
// > conversions to private or protected or ambiguous classes <
|
||||||
|
// > o a qualification conversion <
|
||||||
|
// * the handler is a pointer or pointer to member type and E is
|
||||||
|
// std::nullptr_t
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
#include "third_party/libcxx/exception"
|
||||||
|
#include "libc/isystem/stdlib.h"
|
||||||
|
#include "libc/isystem/assert.h"
|
||||||
|
#include "libc/isystem/stdio.h"
|
||||||
|
|
||||||
|
struct Base {};
|
||||||
|
struct Derived : Base {};
|
||||||
|
struct Derived2 : Base {};
|
||||||
|
struct Ambiguous : Derived, Derived2 {};
|
||||||
|
struct Private : private Base {};
|
||||||
|
struct Protected : protected Base {};
|
||||||
|
|
||||||
|
template <typename T // Handler type
|
||||||
|
,typename E // Thrown exception type
|
||||||
|
,typename O // Object type
|
||||||
|
>
|
||||||
|
void assert_catches()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
O o;
|
||||||
|
throw static_cast<E>(&o);
|
||||||
|
printf("%s\n", __PRETTY_FUNCTION__);
|
||||||
|
assert(false && "Statements after throw must be unreachable");
|
||||||
|
}
|
||||||
|
catch (T t)
|
||||||
|
{
|
||||||
|
assert(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
printf("%s\n", __PRETTY_FUNCTION__);
|
||||||
|
assert(false && "Should not have entered catch-all");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s\n", __PRETTY_FUNCTION__);
|
||||||
|
assert(false && "The catch should have returned");
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T // Handler type
|
||||||
|
,typename E // Thrown exception type
|
||||||
|
,typename O // Object type
|
||||||
|
>
|
||||||
|
void assert_cannot_catch()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
O o;
|
||||||
|
throw static_cast<E>(&o);
|
||||||
|
printf("%s\n", __PRETTY_FUNCTION__);
|
||||||
|
assert(false && "Statements after throw must be unreachable");
|
||||||
|
}
|
||||||
|
catch (T t)
|
||||||
|
{
|
||||||
|
printf("%s\n", __PRETTY_FUNCTION__);
|
||||||
|
assert(false && "Should not have entered the catch");
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s\n", __PRETTY_FUNCTION__);
|
||||||
|
assert(false && "The catch-all should have returned");
|
||||||
|
}
|
||||||
|
|
||||||
|
void f1()
|
||||||
|
{
|
||||||
|
// Test that every combination of handler of type:
|
||||||
|
// cv1 Base * cv2
|
||||||
|
// catches an exception of type:
|
||||||
|
// Derived *
|
||||||
|
assert_catches< Base * , Derived *, Derived>();
|
||||||
|
assert_catches<const Base * , Derived *, Derived>();
|
||||||
|
assert_catches< volatile Base * , Derived *, Derived>();
|
||||||
|
assert_catches<const volatile Base * , Derived *, Derived>();
|
||||||
|
assert_catches< Base * const , Derived *, Derived>();
|
||||||
|
assert_catches<const Base * const , Derived *, Derived>();
|
||||||
|
assert_catches< volatile Base * const , Derived *, Derived>();
|
||||||
|
assert_catches<const volatile Base * const , Derived *, Derived>();
|
||||||
|
assert_catches< Base * volatile, Derived *, Derived>();
|
||||||
|
assert_catches<const Base * volatile, Derived *, Derived>();
|
||||||
|
assert_catches< volatile Base * volatile, Derived *, Derived>();
|
||||||
|
assert_catches<const volatile Base * volatile, Derived *, Derived>();
|
||||||
|
assert_catches< Base * const volatile, Derived *, Derived>();
|
||||||
|
assert_catches<const Base * const volatile, Derived *, Derived>();
|
||||||
|
assert_catches< volatile Base * const volatile, Derived *, Derived>();
|
||||||
|
assert_catches<const volatile Base * const volatile, Derived *, Derived>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void f2()
|
||||||
|
{
|
||||||
|
// Test that every combination of handler of type:
|
||||||
|
// cv1 Base * cv2
|
||||||
|
// catches an exception of type:
|
||||||
|
// Base *
|
||||||
|
assert_catches< Base * , Base *, Derived>();
|
||||||
|
assert_catches<const Base * , Base *, Derived>();
|
||||||
|
assert_catches< volatile Base * , Base *, Derived>();
|
||||||
|
assert_catches<const volatile Base * , Base *, Derived>();
|
||||||
|
assert_catches< Base * const , Base *, Derived>();
|
||||||
|
assert_catches<const Base * const , Base *, Derived>();
|
||||||
|
assert_catches< volatile Base * const , Base *, Derived>();
|
||||||
|
assert_catches<const volatile Base * const , Base *, Derived>();
|
||||||
|
assert_catches< Base * volatile, Base *, Derived>();
|
||||||
|
assert_catches<const Base * volatile, Base *, Derived>();
|
||||||
|
assert_catches< volatile Base * volatile, Base *, Derived>();
|
||||||
|
assert_catches<const volatile Base * volatile, Base *, Derived>();
|
||||||
|
assert_catches< Base * const volatile, Base *, Derived>();
|
||||||
|
assert_catches<const Base * const volatile, Base *, Derived>();
|
||||||
|
assert_catches< volatile Base * const volatile, Base *, Derived>();
|
||||||
|
assert_catches<const volatile Base * const volatile, Base *, Derived>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void f3()
|
||||||
|
{
|
||||||
|
// Test that every combination of handler of type:
|
||||||
|
// cv1 Derived * cv2
|
||||||
|
// catches an exception of type:
|
||||||
|
// Derived *
|
||||||
|
assert_catches< Derived * , Derived *, Derived>();
|
||||||
|
assert_catches<const Derived * , Derived *, Derived>();
|
||||||
|
assert_catches< volatile Derived * , Derived *, Derived>();
|
||||||
|
assert_catches<const volatile Derived * , Derived *, Derived>();
|
||||||
|
assert_catches< Derived * const , Derived *, Derived>();
|
||||||
|
assert_catches<const Derived * const , Derived *, Derived>();
|
||||||
|
assert_catches< volatile Derived * const , Derived *, Derived>();
|
||||||
|
assert_catches<const volatile Derived * const , Derived *, Derived>();
|
||||||
|
assert_catches< Derived * volatile, Derived *, Derived>();
|
||||||
|
assert_catches<const Derived * volatile, Derived *, Derived>();
|
||||||
|
assert_catches< volatile Derived * volatile, Derived *, Derived>();
|
||||||
|
assert_catches<const volatile Derived * volatile, Derived *, Derived>();
|
||||||
|
assert_catches< Derived * const volatile, Derived *, Derived>();
|
||||||
|
assert_catches<const Derived * const volatile, Derived *, Derived>();
|
||||||
|
assert_catches< volatile Derived * const volatile, Derived *, Derived>();
|
||||||
|
assert_catches<const volatile Derived * const volatile, Derived *, Derived>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void f4()
|
||||||
|
{
|
||||||
|
// Test that every combination of handler of type:
|
||||||
|
// cv1 Derived * cv2
|
||||||
|
// cannot catch an exception of type:
|
||||||
|
// Base *
|
||||||
|
assert_cannot_catch< Derived * , Base *, Derived>();
|
||||||
|
assert_cannot_catch<const Derived * , Base *, Derived>();
|
||||||
|
assert_cannot_catch< volatile Derived * , Base *, Derived>();
|
||||||
|
assert_cannot_catch<const volatile Derived * , Base *, Derived>();
|
||||||
|
assert_cannot_catch< Derived * const , Base *, Derived>();
|
||||||
|
assert_cannot_catch<const Derived * const , Base *, Derived>();
|
||||||
|
assert_cannot_catch< volatile Derived * const , Base *, Derived>();
|
||||||
|
assert_cannot_catch<const volatile Derived * const , Base *, Derived>();
|
||||||
|
assert_cannot_catch< Derived * volatile, Base *, Derived>();
|
||||||
|
assert_cannot_catch<const Derived * volatile, Base *, Derived>();
|
||||||
|
assert_cannot_catch< volatile Derived * volatile, Base *, Derived>();
|
||||||
|
assert_cannot_catch<const volatile Derived * volatile, Base *, Derived>();
|
||||||
|
assert_cannot_catch< Derived * const volatile, Base *, Derived>();
|
||||||
|
assert_cannot_catch<const Derived * const volatile, Base *, Derived>();
|
||||||
|
assert_cannot_catch< volatile Derived * const volatile, Base *, Derived>();
|
||||||
|
assert_cannot_catch<const volatile Derived * const volatile, Base *, Derived>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void f5()
|
||||||
|
{
|
||||||
|
// Test that every combination of handler of type:
|
||||||
|
// cv1 Derived * cv2 &
|
||||||
|
// catches an exception of type:
|
||||||
|
// Derived *
|
||||||
|
assert_catches< Derived * &, Derived *, Derived>();
|
||||||
|
assert_catches<const Derived * &, Derived *, Derived>();
|
||||||
|
assert_catches< volatile Derived * &, Derived *, Derived>();
|
||||||
|
assert_catches<const volatile Derived * &, Derived *, Derived>();
|
||||||
|
assert_catches< Derived * const &, Derived *, Derived>();
|
||||||
|
assert_catches<const Derived * const &, Derived *, Derived>();
|
||||||
|
assert_catches< volatile Derived * const &, Derived *, Derived>();
|
||||||
|
assert_catches<const volatile Derived * const &, Derived *, Derived>();
|
||||||
|
assert_catches< Derived * volatile &, Derived *, Derived>();
|
||||||
|
assert_catches<const Derived * volatile &, Derived *, Derived>();
|
||||||
|
assert_catches< volatile Derived * volatile &, Derived *, Derived>();
|
||||||
|
assert_catches<const volatile Derived * volatile &, Derived *, Derived>();
|
||||||
|
assert_catches< Derived * const volatile &, Derived *, Derived>();
|
||||||
|
assert_catches<const Derived * const volatile &, Derived *, Derived>();
|
||||||
|
assert_catches< volatile Derived * const volatile &, Derived *, Derived>();
|
||||||
|
assert_catches<const volatile Derived * const volatile &, Derived *, Derived>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void f6()
|
||||||
|
{
|
||||||
|
// Test that every combination of handler of type:
|
||||||
|
// cv1 Base * cv2 &
|
||||||
|
// catches an exception of type:
|
||||||
|
// Base *
|
||||||
|
assert_catches< Base * &, Base *, Derived>();
|
||||||
|
assert_catches<const Base * &, Base *, Derived>();
|
||||||
|
assert_catches< volatile Base * &, Base *, Derived>();
|
||||||
|
assert_catches<const volatile Base * &, Base *, Derived>();
|
||||||
|
assert_catches< Base * const &, Base *, Derived>();
|
||||||
|
assert_catches<const Base * const &, Base *, Derived>();
|
||||||
|
assert_catches< volatile Base * const &, Base *, Derived>();
|
||||||
|
assert_catches<const volatile Base * const &, Base *, Derived>();
|
||||||
|
assert_catches< Base * volatile &, Base *, Derived>();
|
||||||
|
assert_catches<const Base * volatile &, Base *, Derived>();
|
||||||
|
assert_catches< volatile Base * volatile &, Base *, Derived>();
|
||||||
|
assert_catches<const volatile Base * volatile &, Base *, Derived>();
|
||||||
|
assert_catches< Base * const volatile &, Base *, Derived>();
|
||||||
|
assert_catches<const Base * const volatile &, Base *, Derived>();
|
||||||
|
assert_catches< volatile Base * const volatile &, Base *, Derived>();
|
||||||
|
assert_catches<const volatile Base * const volatile &, Base *, Derived>();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void f7()
|
||||||
|
{
|
||||||
|
// Test that every combination of handler of type:
|
||||||
|
// cv1 Derived * cv2 &
|
||||||
|
// cannot catch an exception of type:
|
||||||
|
// Base *
|
||||||
|
assert_cannot_catch< Derived * &, Base *, Derived>();
|
||||||
|
assert_cannot_catch<const Derived * &, Base *, Derived>();
|
||||||
|
assert_cannot_catch< volatile Derived * &, Base *, Derived>();
|
||||||
|
assert_cannot_catch<const volatile Derived * &, Base *, Derived>();
|
||||||
|
assert_cannot_catch< Derived * const &, Base *, Derived>();
|
||||||
|
assert_cannot_catch<const Derived * const &, Base *, Derived>();
|
||||||
|
assert_cannot_catch< volatile Derived * const &, Base *, Derived>();
|
||||||
|
assert_cannot_catch<const volatile Derived * const &, Base *, Derived>();
|
||||||
|
assert_cannot_catch< Derived * volatile &, Base *, Derived>();
|
||||||
|
assert_cannot_catch<const Derived * volatile &, Base *, Derived>();
|
||||||
|
assert_cannot_catch< volatile Derived * volatile &, Base *, Derived>();
|
||||||
|
assert_cannot_catch<const volatile Derived * volatile &, Base *, Derived>();
|
||||||
|
assert_cannot_catch< Derived * const volatile &, Base *, Derived>();
|
||||||
|
assert_cannot_catch<const Derived * const volatile &, Base *, Derived>();
|
||||||
|
assert_cannot_catch< volatile Derived * const volatile &, Base *, Derived>();
|
||||||
|
assert_cannot_catch<const volatile Derived * const volatile &, Base *, Derived>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void f8()
|
||||||
|
{
|
||||||
|
// This test case has a caveat noted in the discussion here:
|
||||||
|
// https://gcc.gnu.org/ml/gcc-patches/2009-08/msg00264.html
|
||||||
|
// Specifically:
|
||||||
|
// This [test exposes a] corner case of the ARM C++ ABI. The generic C++
|
||||||
|
// ABI also gets this wrong, because I failed to notice the subtlety here.
|
||||||
|
// The issue is that 15.3/3 3rd bullet says:
|
||||||
|
// The handler is of type cv1 T* cv2 and E is a pointer type that
|
||||||
|
// can be converted to the type of the handler by either or both of:
|
||||||
|
// * a standard pointer conversion (4.10) not involving conversions
|
||||||
|
// to pointers to private or protected or ambiguous classes
|
||||||
|
// Notice that the handlers of type "cv1 T*cv2&" are not allowed such
|
||||||
|
// freedom to find a base class. The ABI error is that we treat handlers
|
||||||
|
// of reference type exactly the same as the corresponding hander of
|
||||||
|
// non-reference type. Elsewhere in the exception handling this makes no
|
||||||
|
// difference (for instance bullet 1 explicitly says 'cv T or cv T&').
|
||||||
|
//
|
||||||
|
// See also: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#388
|
||||||
|
//
|
||||||
|
// TL;DR: it is an unresolved C++ ABI defect that these do catch
|
||||||
|
|
||||||
|
// Test that every combination of handler of type:
|
||||||
|
// cv1 Base * cv2 &
|
||||||
|
// catches an exception of type:
|
||||||
|
// Derived *
|
||||||
|
assert_catches< Base * &, Derived *, Derived>();
|
||||||
|
assert_catches<const Base * &, Derived *, Derived>();
|
||||||
|
assert_catches< volatile Base * &, Derived *, Derived>();
|
||||||
|
assert_catches<const volatile Base * &, Derived *, Derived>();
|
||||||
|
assert_catches< Base * const &, Derived *, Derived>();
|
||||||
|
assert_catches<const Base * const &, Derived *, Derived>();
|
||||||
|
assert_catches< volatile Base * const &, Derived *, Derived>();
|
||||||
|
assert_catches<const volatile Base * const &, Derived *, Derived>();
|
||||||
|
assert_catches< Base * volatile &, Derived *, Derived>();
|
||||||
|
assert_catches<const Base * volatile &, Derived *, Derived>();
|
||||||
|
assert_catches< volatile Base * volatile &, Derived *, Derived>();
|
||||||
|
assert_catches<const volatile Base * volatile &, Derived *, Derived>();
|
||||||
|
assert_catches< Base * const volatile &, Derived *, Derived>();
|
||||||
|
assert_catches<const Base * const volatile &, Derived *, Derived>();
|
||||||
|
assert_catches< volatile Base * const volatile &, Derived *, Derived>();
|
||||||
|
assert_catches<const volatile Base * const volatile &, Derived *, Derived>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void f9()
|
||||||
|
{
|
||||||
|
// Test that every combination of handler of type:
|
||||||
|
// cv1 Base * cv2
|
||||||
|
// cannot catch an exception of type:
|
||||||
|
// Ambiguous *
|
||||||
|
assert_cannot_catch< Base * , Ambiguous *, Ambiguous>();
|
||||||
|
assert_cannot_catch<const Base * , Ambiguous *, Ambiguous>();
|
||||||
|
assert_cannot_catch< volatile Base * , Ambiguous *, Ambiguous>();
|
||||||
|
assert_cannot_catch<const volatile Base * , Ambiguous *, Ambiguous>();
|
||||||
|
assert_cannot_catch< Base * const , Ambiguous *, Ambiguous>();
|
||||||
|
assert_cannot_catch<const Base * const , Ambiguous *, Ambiguous>();
|
||||||
|
assert_cannot_catch< volatile Base * const , Ambiguous *, Ambiguous>();
|
||||||
|
assert_cannot_catch<const volatile Base * const , Ambiguous *, Ambiguous>();
|
||||||
|
assert_cannot_catch< Base * volatile, Ambiguous *, Ambiguous>();
|
||||||
|
assert_cannot_catch<const Base * volatile, Ambiguous *, Ambiguous>();
|
||||||
|
assert_cannot_catch< volatile Base * volatile, Ambiguous *, Ambiguous>();
|
||||||
|
assert_cannot_catch<const volatile Base * volatile, Ambiguous *, Ambiguous>();
|
||||||
|
assert_cannot_catch< Base * const volatile, Ambiguous *, Ambiguous>();
|
||||||
|
assert_cannot_catch<const Base * const volatile, Ambiguous *, Ambiguous>();
|
||||||
|
assert_cannot_catch< volatile Base * const volatile, Ambiguous *, Ambiguous>();
|
||||||
|
assert_cannot_catch<const volatile Base * const volatile, Ambiguous *, Ambiguous>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void f10()
|
||||||
|
{
|
||||||
|
// Test that every combination of handler of type:
|
||||||
|
// cv1 Base * cv2
|
||||||
|
// cannot catch an exception of type:
|
||||||
|
// Private *
|
||||||
|
assert_cannot_catch< Base * , Private *, Private>();
|
||||||
|
assert_cannot_catch<const Base * , Private *, Private>();
|
||||||
|
assert_cannot_catch< volatile Base * , Private *, Private>();
|
||||||
|
assert_cannot_catch<const volatile Base * , Private *, Private>();
|
||||||
|
assert_cannot_catch< Base * const , Private *, Private>();
|
||||||
|
assert_cannot_catch<const Base * const , Private *, Private>();
|
||||||
|
assert_cannot_catch< volatile Base * const , Private *, Private>();
|
||||||
|
assert_cannot_catch<const volatile Base * const , Private *, Private>();
|
||||||
|
assert_cannot_catch< Base * volatile, Private *, Private>();
|
||||||
|
assert_cannot_catch<const Base * volatile, Private *, Private>();
|
||||||
|
assert_cannot_catch< volatile Base * volatile, Private *, Private>();
|
||||||
|
assert_cannot_catch<const volatile Base * volatile, Private *, Private>();
|
||||||
|
assert_cannot_catch< Base * const volatile, Private *, Private>();
|
||||||
|
assert_cannot_catch<const Base * const volatile, Private *, Private>();
|
||||||
|
assert_cannot_catch< volatile Base * const volatile, Private *, Private>();
|
||||||
|
assert_cannot_catch<const volatile Base * const volatile, Private *, Private>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void f11()
|
||||||
|
{
|
||||||
|
// Test that every combination of handler of type:
|
||||||
|
// cv1 Base * cv2
|
||||||
|
// cannot catch an exception of type:
|
||||||
|
// Protected *
|
||||||
|
assert_cannot_catch< Base * , Protected *, Protected>();
|
||||||
|
assert_cannot_catch<const Base * , Protected *, Protected>();
|
||||||
|
assert_cannot_catch< volatile Base * , Protected *, Protected>();
|
||||||
|
assert_cannot_catch<const volatile Base * , Protected *, Protected>();
|
||||||
|
assert_cannot_catch< Base * const , Protected *, Protected>();
|
||||||
|
assert_cannot_catch<const Base * const , Protected *, Protected>();
|
||||||
|
assert_cannot_catch< volatile Base * const , Protected *, Protected>();
|
||||||
|
assert_cannot_catch<const volatile Base * const , Protected *, Protected>();
|
||||||
|
assert_cannot_catch< Base * volatile, Protected *, Protected>();
|
||||||
|
assert_cannot_catch<const Base * volatile, Protected *, Protected>();
|
||||||
|
assert_cannot_catch< volatile Base * volatile, Protected *, Protected>();
|
||||||
|
assert_cannot_catch<const volatile Base * volatile, Protected *, Protected>();
|
||||||
|
assert_cannot_catch< Base * const volatile, Protected *, Protected>();
|
||||||
|
assert_cannot_catch<const Base * const volatile, Protected *, Protected>();
|
||||||
|
assert_cannot_catch< volatile Base * const volatile, Protected *, Protected>();
|
||||||
|
assert_cannot_catch<const volatile Base * const volatile, Protected *, Protected>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void f12()
|
||||||
|
{
|
||||||
|
// Test that every combination of handler of type:
|
||||||
|
// cv1 Base * cv2 &
|
||||||
|
// cannot catch an exception of type:
|
||||||
|
// Private *
|
||||||
|
assert_cannot_catch< Base * &, Private *, Private>();
|
||||||
|
assert_cannot_catch<const Base * &, Private *, Private>();
|
||||||
|
assert_cannot_catch< volatile Base * &, Private *, Private>();
|
||||||
|
assert_cannot_catch<const volatile Base * &, Private *, Private>();
|
||||||
|
assert_cannot_catch< Base * const &, Private *, Private>();
|
||||||
|
assert_cannot_catch<const Base * const &, Private *, Private>();
|
||||||
|
assert_cannot_catch< volatile Base * const &, Private *, Private>();
|
||||||
|
assert_cannot_catch<const volatile Base * const &, Private *, Private>();
|
||||||
|
assert_cannot_catch< Base * volatile &, Private *, Private>();
|
||||||
|
assert_cannot_catch<const Base * volatile &, Private *, Private>();
|
||||||
|
assert_cannot_catch< volatile Base * volatile &, Private *, Private>();
|
||||||
|
assert_cannot_catch<const volatile Base * volatile &, Private *, Private>();
|
||||||
|
assert_cannot_catch< Base * const volatile &, Private *, Private>();
|
||||||
|
assert_cannot_catch<const Base * const volatile &, Private *, Private>();
|
||||||
|
assert_cannot_catch< volatile Base * const volatile &, Private *, Private>();
|
||||||
|
assert_cannot_catch<const volatile Base * const volatile &, Private *, Private>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void f13()
|
||||||
|
{
|
||||||
|
// Test that every combination of handler of type:
|
||||||
|
// cv1 Base * cv2 &
|
||||||
|
// cannot catch an exception of type:
|
||||||
|
// Protected *
|
||||||
|
assert_cannot_catch< Base * &, Protected *, Protected>();
|
||||||
|
assert_cannot_catch<const Base * &, Protected *, Protected>();
|
||||||
|
assert_cannot_catch< volatile Base * &, Protected *, Protected>();
|
||||||
|
assert_cannot_catch<const volatile Base * &, Protected *, Protected>();
|
||||||
|
assert_cannot_catch< Base * const &, Protected *, Protected>();
|
||||||
|
assert_cannot_catch<const Base * const &, Protected *, Protected>();
|
||||||
|
assert_cannot_catch< volatile Base * const &, Protected *, Protected>();
|
||||||
|
assert_cannot_catch<const volatile Base * const &, Protected *, Protected>();
|
||||||
|
assert_cannot_catch< Base * volatile &, Protected *, Protected>();
|
||||||
|
assert_cannot_catch<const Base * volatile &, Protected *, Protected>();
|
||||||
|
assert_cannot_catch< volatile Base * volatile &, Protected *, Protected>();
|
||||||
|
assert_cannot_catch<const volatile Base * volatile &, Protected *, Protected>();
|
||||||
|
assert_cannot_catch< Base * const volatile &, Protected *, Protected>();
|
||||||
|
assert_cannot_catch<const Base * const volatile &, Protected *, Protected>();
|
||||||
|
assert_cannot_catch< volatile Base * const volatile &, Protected *, Protected>();
|
||||||
|
assert_cannot_catch<const volatile Base * const volatile &, Protected *, Protected>();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
f1();
|
||||||
|
f2();
|
||||||
|
f3();
|
||||||
|
f4();
|
||||||
|
f5();
|
||||||
|
f6();
|
||||||
|
f7();
|
||||||
|
f8();
|
||||||
|
f9();
|
||||||
|
f10();
|
||||||
|
f11();
|
||||||
|
f12();
|
||||||
|
f13();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
189
third_party/libcxxabi/test/catch_ptr.pass.cc
vendored
Normal file
189
third_party/libcxxabi/test/catch_ptr.pass.cc
vendored
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
/*
|
||||||
|
This test checks that adjustedPtr is correct as there exist offsets in this
|
||||||
|
object for the various subobjects, all of which have a unique id_ to
|
||||||
|
check against. It also checks that virtual bases work properly
|
||||||
|
*/
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
// Compilers emit warnings about exceptions of type 'Child' being caught by
|
||||||
|
// an earlier handler of type 'Base'. Congrats, you've just diagnosed the
|
||||||
|
// behavior under test.
|
||||||
|
// ADDITIONAL_COMPILE_FLAGS: -Wno-exceptions
|
||||||
|
|
||||||
|
#include "third_party/libcxx/exception"
|
||||||
|
#include "libc/isystem/stdlib.h"
|
||||||
|
#include "libc/isystem/assert.h"
|
||||||
|
|
||||||
|
struct B
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
explicit B(int id) : id_(id) {count++;}
|
||||||
|
B(const B& a) : id_(a.id_) {count++;}
|
||||||
|
~B() {count--;}
|
||||||
|
};
|
||||||
|
|
||||||
|
int B::count = 0;
|
||||||
|
|
||||||
|
struct C1
|
||||||
|
: virtual B
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
explicit C1(int id) : B(id-2), id_(id) {count++;}
|
||||||
|
C1(const C1& a) : B(a.id_-2), id_(a.id_) {count++;}
|
||||||
|
~C1() {count--;}
|
||||||
|
};
|
||||||
|
|
||||||
|
int C1::count = 0;
|
||||||
|
|
||||||
|
struct C2
|
||||||
|
: virtual private B
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
explicit C2(int id) : B(id-2), id_(id) {count++;}
|
||||||
|
C2(const C2& a) : B(a.id_-2), id_(a.id_) {count++;}
|
||||||
|
~C2() {count--;}
|
||||||
|
};
|
||||||
|
|
||||||
|
int C2::count = 0;
|
||||||
|
|
||||||
|
struct A
|
||||||
|
: C1, C2
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
explicit A(int id) : B(id+3), C1(id-1), C2(id-2), id_(id) {count++;}
|
||||||
|
A(const A& a) : B(a.id_+3), C1(a.id_-1), C2(a.id_-2), id_(a.id_) {count++;}
|
||||||
|
~A() {count--;}
|
||||||
|
};
|
||||||
|
|
||||||
|
int A::count = 0;
|
||||||
|
|
||||||
|
A global_a(5);
|
||||||
|
|
||||||
|
void f1()
|
||||||
|
{
|
||||||
|
throw &global_a;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void f2()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f1();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const A* a) // can catch A
|
||||||
|
{
|
||||||
|
assert(a->id_ == 5);
|
||||||
|
assert(static_cast<const C1*>(a)->id_ == 4);
|
||||||
|
assert(static_cast<const C2*>(a)->id_ == 3);
|
||||||
|
assert(static_cast<const B*>(a)->id_ == 8);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (const C1*)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const C2*)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const B*)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void f3()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f2();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const B* a) // can catch B
|
||||||
|
{
|
||||||
|
assert(static_cast<const B*>(a)->id_ == 8);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (const C1* c1)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const C2*)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void f4()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f3();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const C2* c2) // can catch C2
|
||||||
|
{
|
||||||
|
assert(c2->id_ == 3);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (const B* a)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const C1*)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void f5()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f4();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const C1* c1) // can catch C1
|
||||||
|
{
|
||||||
|
assert(c1->id_ == 4);
|
||||||
|
assert(static_cast<const B*>(c1)->id_ == 8);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (const B* a)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const C2*)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f5();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
217
third_party/libcxxabi/test/catch_ptr_02.pass.cc
vendored
Normal file
217
third_party/libcxxabi/test/catch_ptr_02.pass.cc
vendored
Normal file
|
@ -0,0 +1,217 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
// Compilers emit warnings about exceptions of type 'Child' being caught by
|
||||||
|
// an earlier handler of type 'Base'. Congrats, you've just diagnosed the
|
||||||
|
// behavior under test.
|
||||||
|
// ADDITIONAL_COMPILE_FLAGS: -Wno-exceptions
|
||||||
|
|
||||||
|
// The fix for PR17222 made it in the dylib for macOS 10.10
|
||||||
|
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.9
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
#include "libc/isystem/stdint.h"
|
||||||
|
|
||||||
|
#if __cplusplus < 201103L
|
||||||
|
#define DISABLE_NULLPTR_TESTS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct A {};
|
||||||
|
A a;
|
||||||
|
const A ca = A();
|
||||||
|
|
||||||
|
void test1 ()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw &a;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch ( const A* )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch ( A *)
|
||||||
|
{
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test2 ()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw &a;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch ( A* )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch ( const A *)
|
||||||
|
{
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test3 ()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw &ca;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch ( const A* )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch ( A *)
|
||||||
|
{
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test4 ()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw &ca;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch ( A *)
|
||||||
|
{
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
catch ( const A* )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct base1 {int x;};
|
||||||
|
struct base2 {int x;};
|
||||||
|
struct derived : base1, base2 {};
|
||||||
|
|
||||||
|
void test5 ()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw (derived*)0;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (base2 *p) {
|
||||||
|
assert (p == 0);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test6 ()
|
||||||
|
{
|
||||||
|
#if !defined(DISABLE_NULLPTR_TESTS)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw nullptr;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (base2 *p) {
|
||||||
|
assert (p == nullptr);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void test7 ()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw (derived*)12;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (base2 *p) {
|
||||||
|
assert ((uintptr_t)p == 12+sizeof(base1));
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct vBase {};
|
||||||
|
struct vDerived : virtual public vBase {};
|
||||||
|
|
||||||
|
void test8 ()
|
||||||
|
{
|
||||||
|
vDerived derived;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw &derived;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (vBase *p) {
|
||||||
|
assert(p != 0);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test9 ()
|
||||||
|
{
|
||||||
|
#if !defined(DISABLE_NULLPTR_TESTS)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw nullptr;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (vBase *p) {
|
||||||
|
assert(p == 0);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void test10 ()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw (vDerived*)0;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (vBase *p) {
|
||||||
|
assert(p == 0);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
test1();
|
||||||
|
test2();
|
||||||
|
test3();
|
||||||
|
test4();
|
||||||
|
test5();
|
||||||
|
test6();
|
||||||
|
test7();
|
||||||
|
test8();
|
||||||
|
test9();
|
||||||
|
test10();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
53
third_party/libcxxabi/test/catch_reference_nullptr.pass.cc
vendored
Normal file
53
third_party/libcxxabi/test/catch_reference_nullptr.pass.cc
vendored
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++03
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
#include "third_party/libcxx/cstddef"
|
||||||
|
#include "third_party/libcxx/cstdlib"
|
||||||
|
#include "third_party/libcxx/type_traits"
|
||||||
|
|
||||||
|
struct A {};
|
||||||
|
|
||||||
|
template<typename T, bool CanCatchNullptr>
|
||||||
|
static void catch_nullptr_test() {
|
||||||
|
try {
|
||||||
|
throw nullptr;
|
||||||
|
} catch (T &p) {
|
||||||
|
assert(CanCatchNullptr && !static_cast<bool>(p));
|
||||||
|
} catch (...) {
|
||||||
|
assert(!CanCatchNullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
static_assert(std::is_same<std::nullptr_t, decltype(nullptr)>::value, "");
|
||||||
|
|
||||||
|
// A reference to nullptr_t can catch nullptr.
|
||||||
|
catch_nullptr_test<std::nullptr_t, true>();
|
||||||
|
catch_nullptr_test<const std::nullptr_t, true>();
|
||||||
|
catch_nullptr_test<volatile std::nullptr_t, true>();
|
||||||
|
catch_nullptr_test<const volatile std::nullptr_t, true>();
|
||||||
|
|
||||||
|
// No other reference type can.
|
||||||
|
#if 0
|
||||||
|
// FIXME: These tests fail, because the ABI provides no way for us to
|
||||||
|
// distinguish this from catching by value.
|
||||||
|
catch_nullptr_test<void *, false>();
|
||||||
|
catch_nullptr_test<void * const, false>();
|
||||||
|
catch_nullptr_test<int *, false>();
|
||||||
|
catch_nullptr_test<A *, false>();
|
||||||
|
catch_nullptr_test<int A::*, false>();
|
||||||
|
catch_nullptr_test<int (A::*)(), false>();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
57
third_party/libcxxabi/test/cxa_bad_cast.pass.cc
vendored
Normal file
57
third_party/libcxxabi/test/cxa_bad_cast.pass.cc
vendored
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++03
|
||||||
|
|
||||||
|
#include "third_party/libcxxabi/include/cxxabi.h"
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
#include "libc/isystem/stdlib.h"
|
||||||
|
#include "third_party/libcxx/exception"
|
||||||
|
#include "third_party/libcxx/typeinfo"
|
||||||
|
|
||||||
|
#include "third_party/libcxxabi/libcxx/test/support/test_macros.hh"
|
||||||
|
|
||||||
|
class Base {
|
||||||
|
virtual void foo() {};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Derived : public Base {};
|
||||||
|
|
||||||
|
Derived &test_bad_cast(Base& b) {
|
||||||
|
return dynamic_cast<Derived&>(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
Base gB;
|
||||||
|
|
||||||
|
void my_terminate() { exit(0); }
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
// swap-out the terminate handler
|
||||||
|
void (*default_handler)() = std::get_terminate();
|
||||||
|
std::set_terminate(my_terminate);
|
||||||
|
|
||||||
|
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||||
|
try {
|
||||||
|
#endif
|
||||||
|
Derived &d = test_bad_cast(gB);
|
||||||
|
assert(false);
|
||||||
|
((void)d);
|
||||||
|
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||||
|
} catch (std::bad_cast const&) {
|
||||||
|
// success
|
||||||
|
return 0;
|
||||||
|
} catch (...) {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// failure, restore the default terminate handler and fire
|
||||||
|
std::set_terminate(default_handler);
|
||||||
|
std::terminate();
|
||||||
|
}
|
55
third_party/libcxxabi/test/cxa_bad_typeid.pass.cc
vendored
Normal file
55
third_party/libcxxabi/test/cxa_bad_typeid.pass.cc
vendored
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===------------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++03
|
||||||
|
|
||||||
|
#include "third_party/libcxxabi/include/cxxabi.h"
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
#include "libc/isystem/stdlib.h"
|
||||||
|
#include "third_party/libcxx/exception"
|
||||||
|
#include "third_party/libcxx/typeinfo"
|
||||||
|
#include "third_party/libcxx/string"
|
||||||
|
|
||||||
|
#include "third_party/libcxxabi/libcxx/test/support/test_macros.hh"
|
||||||
|
|
||||||
|
class Base {
|
||||||
|
virtual void foo() {};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Derived : public Base {};
|
||||||
|
|
||||||
|
std::string test_bad_typeid(Derived *p) {
|
||||||
|
return typeid(*p).name();
|
||||||
|
}
|
||||||
|
|
||||||
|
void my_terminate() { exit(0); }
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
// swap-out the terminate handler
|
||||||
|
void (*default_handler)() = std::get_terminate();
|
||||||
|
std::set_terminate(my_terminate);
|
||||||
|
|
||||||
|
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||||
|
try {
|
||||||
|
#endif
|
||||||
|
test_bad_typeid(nullptr);
|
||||||
|
assert(false);
|
||||||
|
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||||
|
} catch (std::bad_typeid const&) {
|
||||||
|
// success
|
||||||
|
return 0;
|
||||||
|
} catch (...) {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// failure, restore the default terminate handler and fire
|
||||||
|
std::set_terminate(default_handler);
|
||||||
|
std::terminate();
|
||||||
|
}
|
33
third_party/libcxxabi/test/cxa_thread_atexit_test.pass.cc
vendored
Normal file
33
third_party/libcxxabi/test/cxa_thread_atexit_test.pass.cc
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-threads
|
||||||
|
// REQUIRES: linux
|
||||||
|
|
||||||
|
#include "libc/isystem/assert.h"
|
||||||
|
#include "third_party/libcxxabi/include/cxxabi.h"
|
||||||
|
|
||||||
|
static bool AtexitImplCalled = false;
|
||||||
|
|
||||||
|
extern "C" int __cxa_thread_atexit_impl(void (*dtor)(void *), void *obj,
|
||||||
|
void *dso_symbol) {
|
||||||
|
assert(dtor == reinterpret_cast<void (*)(void *)>(1));
|
||||||
|
assert(obj == reinterpret_cast<void *>(2));
|
||||||
|
assert(dso_symbol == reinterpret_cast<void *>(3));
|
||||||
|
AtexitImplCalled = true;
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
int RV = __cxxabiv1::__cxa_thread_atexit(
|
||||||
|
reinterpret_cast<void (*)(void *)>(1), reinterpret_cast<void *>(2),
|
||||||
|
reinterpret_cast<void *>(3));
|
||||||
|
assert(RV == 4);
|
||||||
|
assert(AtexitImplCalled);
|
||||||
|
return 0;
|
||||||
|
}
|
125
third_party/libcxxabi/test/cxa_vec_new_overflow_PR41395.pass.cc
vendored
Normal file
125
third_party/libcxxabi/test/cxa_vec_new_overflow_PR41395.pass.cc
vendored
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
// PR41395 isn't fixed until the dylib shipped with macOS 10.15
|
||||||
|
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14}}
|
||||||
|
|
||||||
|
#include "third_party/libcxxabi/include/cxxabi.h"
|
||||||
|
#include "third_party/libcxx/new"
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
|
||||||
|
void dummy_ctor(void*) { assert(false && "should not be called"); }
|
||||||
|
void dummy_dtor(void*) { assert(false && "should not be called"); }
|
||||||
|
|
||||||
|
void *dummy_alloc(size_t) { assert(false && "should not be called"); return nullptr; }
|
||||||
|
void dummy_dealloc(void*) { assert(false && "should not be called"); }
|
||||||
|
void dummy_dealloc_sized(void*, size_t) { assert(false && "should not be called"); }
|
||||||
|
|
||||||
|
|
||||||
|
bool check_mul_overflows(size_t x, size_t y) {
|
||||||
|
size_t tmp = x * y;
|
||||||
|
if (tmp / x != y)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool check_add_overflows(size_t x, size_t y) {
|
||||||
|
size_t tmp = x + y;
|
||||||
|
if (tmp < x)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_overflow_in_multiplication() {
|
||||||
|
const size_t elem_count = std::size_t(1) << (sizeof(std::size_t) * 8 - 2);
|
||||||
|
const size_t elem_size = 8;
|
||||||
|
const size_t padding = 0;
|
||||||
|
assert(check_mul_overflows(elem_count, elem_size));
|
||||||
|
|
||||||
|
try {
|
||||||
|
__cxxabiv1::__cxa_vec_new(elem_count, elem_size, padding, dummy_ctor,
|
||||||
|
dummy_dtor);
|
||||||
|
assert(false && "allocation should fail");
|
||||||
|
} catch (std::bad_array_new_length const&) {
|
||||||
|
// OK
|
||||||
|
} catch (...) {
|
||||||
|
assert(false && "unexpected exception");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
__cxxabiv1::__cxa_vec_new2(elem_count, elem_size, padding, dummy_ctor,
|
||||||
|
dummy_dtor, &dummy_alloc, &dummy_dealloc);
|
||||||
|
assert(false && "allocation should fail");
|
||||||
|
} catch (std::bad_array_new_length const&) {
|
||||||
|
// OK
|
||||||
|
} catch (...) {
|
||||||
|
assert(false && "unexpected exception");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
__cxxabiv1::__cxa_vec_new3(elem_count, elem_size, padding, dummy_ctor,
|
||||||
|
dummy_dtor, &dummy_alloc, &dummy_dealloc_sized);
|
||||||
|
assert(false && "allocation should fail");
|
||||||
|
} catch (std::bad_array_new_length const&) {
|
||||||
|
// OK
|
||||||
|
} catch (...) {
|
||||||
|
assert(false && "unexpected exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_overflow_in_addition() {
|
||||||
|
const size_t elem_size = 4;
|
||||||
|
const size_t elem_count = static_cast<size_t>(-1) / 4u;
|
||||||
|
#if defined(_LIBCXXABI_ARM_EHABI)
|
||||||
|
const size_t padding = 8;
|
||||||
|
#else
|
||||||
|
const size_t padding = sizeof(std::size_t);
|
||||||
|
#endif
|
||||||
|
assert(!check_mul_overflows(elem_count, elem_size));
|
||||||
|
assert(check_add_overflows(elem_count * elem_size, padding));
|
||||||
|
try {
|
||||||
|
__cxxabiv1::__cxa_vec_new(elem_count, elem_size, padding, dummy_ctor,
|
||||||
|
dummy_dtor);
|
||||||
|
assert(false && "allocation should fail");
|
||||||
|
} catch (std::bad_array_new_length const&) {
|
||||||
|
// OK
|
||||||
|
} catch (...) {
|
||||||
|
assert(false && "unexpected exception");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
__cxxabiv1::__cxa_vec_new2(elem_count, elem_size, padding, dummy_ctor,
|
||||||
|
dummy_dtor, &dummy_alloc, &dummy_dealloc);
|
||||||
|
assert(false && "allocation should fail");
|
||||||
|
} catch (std::bad_array_new_length const&) {
|
||||||
|
// OK
|
||||||
|
} catch (...) {
|
||||||
|
assert(false && "unexpected exception");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
__cxxabiv1::__cxa_vec_new3(elem_count, elem_size, padding, dummy_ctor,
|
||||||
|
dummy_dtor, &dummy_alloc, &dummy_dealloc_sized);
|
||||||
|
assert(false && "allocation should fail");
|
||||||
|
} catch (std::bad_array_new_length const&) {
|
||||||
|
// OK
|
||||||
|
} catch (...) {
|
||||||
|
assert(false && "unexpected exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
test_overflow_in_multiplication();
|
||||||
|
test_overflow_in_addition();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
163
third_party/libcxxabi/test/dynamic_cast.pass.cc
vendored
Normal file
163
third_party/libcxxabi/test/dynamic_cast.pass.cc
vendored
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// PR33425 and PR33487 are not fixed until the dylib shipped with macOS 10.15
|
||||||
|
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.14
|
||||||
|
|
||||||
|
// PR33439 isn't fixed until the dylib shipped with macOS 10.14
|
||||||
|
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{9|10|11|12|13}}
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
|
||||||
|
// This test explicitly tests dynamic cast with types that have inaccessible
|
||||||
|
// bases.
|
||||||
|
#if defined(__clang__)
|
||||||
|
# pragma clang diagnostic ignored "-Winaccessible-base"
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
# pragma GCC diagnostic ignored "-Winaccessible-base"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef char Pad1[43981];
|
||||||
|
typedef char Pad2[34981];
|
||||||
|
typedef char Pad3[93481];
|
||||||
|
typedef char Pad4[13489];
|
||||||
|
typedef char Pad5[81349];
|
||||||
|
typedef char Pad6[34819];
|
||||||
|
typedef char Pad7[3489];
|
||||||
|
|
||||||
|
namespace t1
|
||||||
|
{
|
||||||
|
|
||||||
|
// PR33425
|
||||||
|
struct C3 { virtual ~C3() {} Pad1 _; };
|
||||||
|
struct C5 : protected virtual C3 { Pad2 _; };
|
||||||
|
struct C6 : virtual C5 { Pad3 _; };
|
||||||
|
struct C7 : virtual C3 { Pad4 _; };
|
||||||
|
struct C9 : C6, C7 { Pad5 _; };
|
||||||
|
|
||||||
|
C9 c9;
|
||||||
|
C3 *c3 = &c9;
|
||||||
|
|
||||||
|
void test()
|
||||||
|
{
|
||||||
|
assert(dynamic_cast<C3*>(c3) == static_cast<C3*>(&c9));
|
||||||
|
assert(dynamic_cast<C5*>(c3) == static_cast<C5*>(&c9));
|
||||||
|
assert(dynamic_cast<C6*>(c3) == static_cast<C6*>(&c9));
|
||||||
|
assert(dynamic_cast<C7*>(c3) == static_cast<C7*>(&c9));
|
||||||
|
assert(dynamic_cast<C9*>(c3) == static_cast<C9*>(&c9));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // t1
|
||||||
|
|
||||||
|
namespace t2
|
||||||
|
{
|
||||||
|
|
||||||
|
// PR33425
|
||||||
|
struct Src { virtual ~Src() {} Pad1 _; };
|
||||||
|
struct Mask : protected virtual Src { Pad2 _; };
|
||||||
|
struct Dest : Mask { Pad3 _; };
|
||||||
|
struct Root : Dest, virtual Src { Pad4 _; };
|
||||||
|
|
||||||
|
Root root;
|
||||||
|
Src *src = &root;
|
||||||
|
|
||||||
|
void test()
|
||||||
|
{
|
||||||
|
assert(dynamic_cast<Src*>(src) == static_cast<Src*>(&root));
|
||||||
|
assert(dynamic_cast<Mask*>(src) == static_cast<Mask*>(&root));
|
||||||
|
assert(dynamic_cast<Dest*>(src) == static_cast<Dest*>(&root));
|
||||||
|
assert(dynamic_cast<Root*>(src) == static_cast<Root*>(&root));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // t2
|
||||||
|
|
||||||
|
namespace t3
|
||||||
|
{
|
||||||
|
|
||||||
|
// PR33487
|
||||||
|
struct Class1 { virtual ~Class1() {} Pad1 _; };
|
||||||
|
struct Shared : virtual Class1 { Pad2 _; };
|
||||||
|
struct Class6 : virtual Shared { Pad3 _; };
|
||||||
|
struct Left : Class6 { Pad4 _; };
|
||||||
|
struct Right : Class6 { Pad5 _; };
|
||||||
|
struct Main : Left, Right { Pad6 _; };
|
||||||
|
|
||||||
|
Main m;
|
||||||
|
Class1 *c1 = &m;
|
||||||
|
|
||||||
|
void test()
|
||||||
|
{
|
||||||
|
assert(dynamic_cast<Class1*>(c1) == static_cast<Class1*>(&m));
|
||||||
|
assert(dynamic_cast<Shared*>(c1) == static_cast<Shared*>(&m));
|
||||||
|
assert(dynamic_cast<Class6*>(c1) == 0);
|
||||||
|
assert(dynamic_cast<Left*>(c1) == static_cast<Left*>(&m));
|
||||||
|
assert(dynamic_cast<Right*>(c1) == static_cast<Right*>(&m));
|
||||||
|
assert(dynamic_cast<Main*>(c1) == static_cast<Main*>(&m));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // t3
|
||||||
|
|
||||||
|
namespace t4
|
||||||
|
{
|
||||||
|
|
||||||
|
// PR33439
|
||||||
|
struct C2 { virtual ~C2() {} Pad1 _; };
|
||||||
|
struct C3 { virtual ~C3() {} Pad2 _; };
|
||||||
|
struct C4 : C3 { Pad3 _; };
|
||||||
|
struct C8 : C2, virtual C4 { Pad4 _; };
|
||||||
|
struct C9 : C4, C8 { Pad5 _; };
|
||||||
|
|
||||||
|
C9 c9;
|
||||||
|
C2 *c2 = &c9;
|
||||||
|
|
||||||
|
void test()
|
||||||
|
{
|
||||||
|
assert(dynamic_cast<C2*>(c2) == static_cast<C2*>(&c9));
|
||||||
|
assert(dynamic_cast<C3*>(c2) == 0);
|
||||||
|
assert(dynamic_cast<C4*>(c2) == 0);
|
||||||
|
assert(dynamic_cast<C8*>(c2) == static_cast<C8*>(&c9));
|
||||||
|
assert(dynamic_cast<C9*>(c2) == static_cast<C9*>(&c9));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // t4
|
||||||
|
|
||||||
|
namespace t5
|
||||||
|
{
|
||||||
|
|
||||||
|
// PR33439
|
||||||
|
struct Dummy { virtual ~Dummy() {} Pad1 _; };
|
||||||
|
struct Src { virtual ~Src() {} Pad2 _; };
|
||||||
|
struct Dest : Dummy { Pad3 _; };
|
||||||
|
struct A1 : Dest { Pad4 _; };
|
||||||
|
struct A2 : Dest { Pad5 _; };
|
||||||
|
struct Root : Src, A1, A2 { Pad6 _; };
|
||||||
|
|
||||||
|
Root root;
|
||||||
|
Src *src = &root;
|
||||||
|
|
||||||
|
void test()
|
||||||
|
{
|
||||||
|
assert(dynamic_cast<Dummy*>(src) == 0);
|
||||||
|
assert(dynamic_cast<Src*>(src) == static_cast<Src*>(&root));
|
||||||
|
assert(dynamic_cast<Dest*>(src) == 0);
|
||||||
|
assert(dynamic_cast<A1*>(src) == static_cast<A1*>(&root));
|
||||||
|
assert(dynamic_cast<A2*>(src) == static_cast<A2*>(&root));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // t5
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
t1::test();
|
||||||
|
t2::test();
|
||||||
|
t3::test();
|
||||||
|
t4::test();
|
||||||
|
t5::test();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
2183
third_party/libcxxabi/test/dynamic_cast14.pass.cc
vendored
Normal file
2183
third_party/libcxxabi/test/dynamic_cast14.pass.cc
vendored
Normal file
File diff suppressed because it is too large
Load diff
2463
third_party/libcxxabi/test/dynamic_cast3.pass.cc
vendored
Normal file
2463
third_party/libcxxabi/test/dynamic_cast3.pass.cc
vendored
Normal file
File diff suppressed because it is too large
Load diff
1324
third_party/libcxxabi/test/dynamic_cast5.pass.cc
vendored
Normal file
1324
third_party/libcxxabi/test/dynamic_cast5.pass.cc
vendored
Normal file
File diff suppressed because it is too large
Load diff
82
third_party/libcxxabi/test/dynamic_cast_stress.pass.cc
vendored
Normal file
82
third_party/libcxxabi/test/dynamic_cast_stress.pass.cc
vendored
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++03
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
#include "third_party/libcxx/tuple"
|
||||||
|
#include "third_party/libcxxabi/test/support/timer.hh"
|
||||||
|
|
||||||
|
template <std::size_t Indx, std::size_t Depth>
|
||||||
|
struct C
|
||||||
|
: public virtual C<Indx, Depth-1>,
|
||||||
|
public virtual C<Indx+1, Depth-1>
|
||||||
|
{
|
||||||
|
virtual ~C() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <std::size_t Indx>
|
||||||
|
struct C<Indx, 0>
|
||||||
|
{
|
||||||
|
virtual ~C() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <std::size_t Indx, std::size_t Depth>
|
||||||
|
struct B
|
||||||
|
: public virtual C<Indx, Depth-1>,
|
||||||
|
public virtual C<Indx+1, Depth-1>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Indx, std::size_t Depth>
|
||||||
|
struct makeB;
|
||||||
|
|
||||||
|
template <std::size_t ...Indx, std::size_t Depth>
|
||||||
|
struct makeB<std::__tuple_indices<Indx...>, Depth>
|
||||||
|
: public B<Indx, Depth>...
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <std::size_t Width, std::size_t Depth>
|
||||||
|
struct A
|
||||||
|
: public makeB<typename std::__make_tuple_indices<Width>::type, Depth>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
void test()
|
||||||
|
{
|
||||||
|
const std::size_t Width = 10;
|
||||||
|
const std::size_t Depth = 5;
|
||||||
|
A<Width, Depth> a;
|
||||||
|
typedef B<Width/2, Depth> Destination;
|
||||||
|
// typedef A<Width, Depth> Destination;
|
||||||
|
Destination *b = nullptr;
|
||||||
|
{
|
||||||
|
timer t;
|
||||||
|
b = dynamic_cast<Destination*>((C<Width/2, 0>*)&a);
|
||||||
|
}
|
||||||
|
assert(b != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
test();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Timing results I'm seeing (median of 3 microseconds):
|
||||||
|
|
||||||
|
libc++abi gcc's dynamic_cast
|
||||||
|
B<Width/2, Depth> -O3 48.334 93.190 libc++abi 93% faster
|
||||||
|
B<Width/2, Depth> -Os 58.535 94.103 libc++abi 61% faster
|
||||||
|
A<Width, Depth> -O3 11.515 33.134 libc++abi 188% faster
|
||||||
|
A<Width, Depth> -Os 12.631 31.553 libc++abi 150% faster
|
||||||
|
|
||||||
|
*/
|
34
third_party/libcxxabi/test/exception_object_alignment.2.pass.cc
vendored
Normal file
34
third_party/libcxxabi/test/exception_object_alignment.2.pass.cc
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
// This test checks that the compiler does not make incorrect assumptions
|
||||||
|
// about the alignment of the exception (only in that specific case, of
|
||||||
|
// course).
|
||||||
|
//
|
||||||
|
// There was a bug where Clang would emit a call to memset assuming a 16-byte
|
||||||
|
// aligned exception even when back-deploying to older Darwin systems where
|
||||||
|
// exceptions are 8-byte aligned, which caused a segfault on those systems.
|
||||||
|
|
||||||
|
struct exception {
|
||||||
|
exception() : x(0) { }
|
||||||
|
virtual ~exception() { }
|
||||||
|
int x;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct foo : exception { };
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
try {
|
||||||
|
throw foo();
|
||||||
|
} catch (...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
39
third_party/libcxxabi/test/exception_object_alignment.pass.cc
vendored
Normal file
39
third_party/libcxxabi/test/exception_object_alignment.pass.cc
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
// The situation for the alignment of exception objects is badly messed up
|
||||||
|
// before macOS 10.14. The test fails on macOS 10.9 to 10.12, passes on macOS
|
||||||
|
// 10.13 (no investigation done), and passes afterwards. Just mark all the OSes
|
||||||
|
// before 10.14 as unsupported.
|
||||||
|
// UNSUPPORTED: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{9|10|11|12|13}}
|
||||||
|
|
||||||
|
// Check that the pointer __cxa_allocate_exception returns is aligned to the
|
||||||
|
// default alignment for the target architecture.
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
#include "third_party/libcxx/cstdint"
|
||||||
|
#include "third_party/libcxxabi/include/cxxabi.h"
|
||||||
|
#include "third_party/libcxx/type_traits"
|
||||||
|
#include "third_party/libcxxabi/include/__cxxabi_config.h"
|
||||||
|
|
||||||
|
struct S {
|
||||||
|
int a[4];
|
||||||
|
} __attribute__((aligned));
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
#if !defined(_LIBCXXABI_ARM_EHABI)
|
||||||
|
void *p = __cxxabiv1::__cxa_allocate_exception(16);
|
||||||
|
auto i = reinterpret_cast<uintptr_t>(p);
|
||||||
|
auto a = std::alignment_of<S>::value;
|
||||||
|
assert(i % a == 0);
|
||||||
|
__cxxabiv1::__cxa_free_exception(p);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
164
third_party/libcxxabi/test/guard_test_basic.pass.cc
vendored
Normal file
164
third_party/libcxxabi/test/guard_test_basic.pass.cc
vendored
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// UNSUPPORTED: c++03
|
||||||
|
|
||||||
|
// Necessary because we include a private header of libc++abi, which
|
||||||
|
// only understands _LIBCXXABI_HAS_NO_THREADS.
|
||||||
|
#include "third_party/libcxxabi/libcxx/test/support/test_macros.hh"
|
||||||
|
#ifdef TEST_HAS_NO_THREADS
|
||||||
|
# define _LIBCXXABI_HAS_NO_THREADS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TESTING_CXA_GUARD
|
||||||
|
#include "third_party/libcxxabi/cxa_guard_impl.h"
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
#include "third_party/libcxx/type_traits"
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
# pragma clang diagnostic ignored "-Wtautological-pointer-compare"
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
# pragma GCC diagnostic ignored "-Waddress"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using namespace __cxxabiv1;
|
||||||
|
|
||||||
|
template <class GuardType, class Impl>
|
||||||
|
struct Tests {
|
||||||
|
private:
|
||||||
|
Tests() : g{}, impl(&g) {}
|
||||||
|
GuardType g;
|
||||||
|
Impl impl;
|
||||||
|
|
||||||
|
uint8_t first_byte() {
|
||||||
|
uint8_t first;
|
||||||
|
std::memcpy(&first, &g, 1);
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() { g = {}; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Test the post conditions on cxa_guard_acquire, cxa_guard_abort, and
|
||||||
|
// cxa_guard_release. Specifically, that they leave the first byte with
|
||||||
|
// the value 0 or 1 as specified by the ARM or Itanium specification.
|
||||||
|
static void test() {
|
||||||
|
Tests tests;
|
||||||
|
tests.test_acquire();
|
||||||
|
tests.test_abort();
|
||||||
|
tests.test_release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_acquire() {
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
assert(first_byte() == 0);
|
||||||
|
assert(impl.cxa_guard_acquire() == INIT_IS_PENDING);
|
||||||
|
assert(first_byte() == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
assert(first_byte() == 0);
|
||||||
|
assert(impl.cxa_guard_acquire() == INIT_IS_PENDING);
|
||||||
|
impl.cxa_guard_release();
|
||||||
|
assert(first_byte() == 1);
|
||||||
|
assert(impl.cxa_guard_acquire() == INIT_IS_DONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_release() {
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
assert(first_byte() == 0);
|
||||||
|
assert(impl.cxa_guard_acquire() == INIT_IS_PENDING);
|
||||||
|
assert(first_byte() == 0);
|
||||||
|
impl.cxa_guard_release();
|
||||||
|
assert(first_byte() == 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_abort() {
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
assert(first_byte() == 0);
|
||||||
|
assert(impl.cxa_guard_acquire() == INIT_IS_PENDING);
|
||||||
|
assert(first_byte() == 0);
|
||||||
|
impl.cxa_guard_abort();
|
||||||
|
assert(first_byte() == 0);
|
||||||
|
assert(impl.cxa_guard_acquire() == INIT_IS_PENDING);
|
||||||
|
assert(first_byte() == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NopMutex {
|
||||||
|
bool lock() {
|
||||||
|
assert(!is_locked);
|
||||||
|
is_locked = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool unlock() {
|
||||||
|
assert(is_locked);
|
||||||
|
is_locked = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool is_locked = false;
|
||||||
|
};
|
||||||
|
NopMutex global_nop_mutex = {};
|
||||||
|
|
||||||
|
struct NopCondVar {
|
||||||
|
bool broadcast() { return false; }
|
||||||
|
bool wait(NopMutex&) { return false; }
|
||||||
|
};
|
||||||
|
NopCondVar global_nop_cond = {};
|
||||||
|
|
||||||
|
void NopFutexWait(int*, int) { assert(false); }
|
||||||
|
void NopFutexWake(int*) { assert(false); }
|
||||||
|
uint32_t MockGetThreadID() { return 0; }
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
{
|
||||||
|
#if defined(TEST_HAS_NO_THREADS)
|
||||||
|
static_assert(CurrentImplementation == Implementation::NoThreads, "");
|
||||||
|
static_assert(std::is_same<SelectedImplementation, NoThreadsGuard>::value, "");
|
||||||
|
#else
|
||||||
|
static_assert(CurrentImplementation == Implementation::GlobalMutex, "");
|
||||||
|
static_assert(std::is_same<SelectedImplementation,
|
||||||
|
GlobalMutexGuard<LibcppMutex, LibcppCondVar, GlobalStatic<LibcppMutex>::instance,
|
||||||
|
GlobalStatic<LibcppCondVar>::instance>>::value,
|
||||||
|
"");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
{
|
||||||
|
#if (defined(__APPLE__) || defined(__linux__)) && !defined(TEST_HAS_NO_THREADS)
|
||||||
|
assert(PlatformThreadID);
|
||||||
|
#endif
|
||||||
|
if (PlatformThreadID != nullptr) {
|
||||||
|
assert(PlatformThreadID() != 0);
|
||||||
|
assert(PlatformThreadID() == PlatformThreadID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Tests<uint32_t, NoThreadsGuard>::test();
|
||||||
|
Tests<uint64_t, NoThreadsGuard>::test();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
using MutexImpl = GlobalMutexGuard<NopMutex, NopCondVar, global_nop_mutex, global_nop_cond, MockGetThreadID>;
|
||||||
|
Tests<uint32_t, MutexImpl>::test();
|
||||||
|
Tests<uint64_t, MutexImpl>::test();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
using FutexImpl = FutexGuard<&NopFutexWait, &NopFutexWake, &MockGetThreadID>;
|
||||||
|
Tests<uint32_t, FutexImpl>::test();
|
||||||
|
Tests<uint64_t, FutexImpl>::test();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
386
third_party/libcxxabi/test/guard_threaded_test.pass.cc
vendored
Normal file
386
third_party/libcxxabi/test/guard_threaded_test.pass.cc
vendored
Normal file
|
@ -0,0 +1,386 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++03
|
||||||
|
// UNSUPPORTED: no-threads
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
#define TESTING_CXA_GUARD
|
||||||
|
#include "third_party/libcxxabi/cxa_guard_impl.h"
|
||||||
|
#include "third_party/libcxx/unordered_map"
|
||||||
|
#include "third_party/libcxx/thread"
|
||||||
|
#include "third_party/libcxx/atomic"
|
||||||
|
#include "third_party/libcxx/array"
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
#include "third_party/libcxx/memory"
|
||||||
|
#include "third_party/libcxx/vector"
|
||||||
|
|
||||||
|
#include "third_party/libcxxabi/libcxx/test/support/make_test_thread.hh"
|
||||||
|
#include "third_party/libcxxabi/libcxx/test/support/test_macros.hh"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace __cxxabiv1;
|
||||||
|
|
||||||
|
// Misc test configuration. It's used to tune the flakyness of the test.
|
||||||
|
// ThreadsPerTest - The number of threads used
|
||||||
|
constexpr int ThreadsPerTest = 10;
|
||||||
|
// The number of instances of a test to run concurrently.
|
||||||
|
constexpr int ConcurrentRunsPerTest = 10;
|
||||||
|
// The number of times to rerun each test.
|
||||||
|
constexpr int TestSamples = 50;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void BusyWait() {
|
||||||
|
std::this_thread::yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
void YieldAfterBarrier() {
|
||||||
|
std::this_thread::sleep_for(std::chrono::nanoseconds(10));
|
||||||
|
std::this_thread::yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Barrier {
|
||||||
|
explicit Barrier(int n) : m_threads(n), m_remaining(n) { }
|
||||||
|
Barrier(Barrier const&) = delete;
|
||||||
|
Barrier& operator=(Barrier const&) = delete;
|
||||||
|
|
||||||
|
void arrive_and_wait() const {
|
||||||
|
--m_remaining;
|
||||||
|
while (m_remaining.load()) {
|
||||||
|
BusyWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void arrive_and_drop() const {
|
||||||
|
--m_remaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wait_for_threads(int n) const {
|
||||||
|
while ((m_threads - m_remaining.load()) < n) {
|
||||||
|
std::this_thread::yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const int m_threads;
|
||||||
|
mutable std::atomic<int> m_remaining;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum class InitResult {
|
||||||
|
COMPLETE,
|
||||||
|
PERFORMED,
|
||||||
|
WAITED,
|
||||||
|
ABORTED
|
||||||
|
};
|
||||||
|
constexpr InitResult COMPLETE = InitResult::COMPLETE;
|
||||||
|
constexpr InitResult PERFORMED = InitResult::PERFORMED;
|
||||||
|
constexpr InitResult WAITED = InitResult::WAITED;
|
||||||
|
constexpr InitResult ABORTED = InitResult::ABORTED;
|
||||||
|
|
||||||
|
|
||||||
|
template <class Impl, class GuardType, class Init>
|
||||||
|
InitResult check_guard(GuardType *g, Init init) {
|
||||||
|
uint8_t *first_byte = reinterpret_cast<uint8_t*>(g);
|
||||||
|
if (std::__libcpp_atomic_load(first_byte, std::_AO_Acquire) == 0) {
|
||||||
|
Impl impl(g);
|
||||||
|
if (impl.cxa_guard_acquire() == INIT_IS_PENDING) {
|
||||||
|
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||||
|
try {
|
||||||
|
#endif
|
||||||
|
init();
|
||||||
|
impl.cxa_guard_release();
|
||||||
|
return PERFORMED;
|
||||||
|
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||||
|
} catch (...) {
|
||||||
|
impl.cxa_guard_abort();
|
||||||
|
return ABORTED;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return WAITED;
|
||||||
|
}
|
||||||
|
return COMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class GuardType, class Impl>
|
||||||
|
struct FunctionLocalStatic {
|
||||||
|
FunctionLocalStatic() {}
|
||||||
|
FunctionLocalStatic(FunctionLocalStatic const&) = delete;
|
||||||
|
|
||||||
|
template <class InitFunc>
|
||||||
|
InitResult access(InitFunc&& init) {
|
||||||
|
auto res = check_guard<Impl>(&guard_object, init);
|
||||||
|
++result_counts[static_cast<int>(res)];
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class InitFn>
|
||||||
|
struct AccessCallback {
|
||||||
|
void operator()() const { this_obj->access(init); }
|
||||||
|
|
||||||
|
FunctionLocalStatic *this_obj;
|
||||||
|
InitFn init;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class InitFn, class Callback = AccessCallback< InitFn > >
|
||||||
|
Callback access_callback(InitFn init) {
|
||||||
|
return Callback{this, init};
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_count(InitResult I) const {
|
||||||
|
return result_counts[static_cast<int>(I)].load();
|
||||||
|
}
|
||||||
|
|
||||||
|
int num_completed() const {
|
||||||
|
return get_count(COMPLETE) + get_count(PERFORMED) + get_count(WAITED);
|
||||||
|
}
|
||||||
|
|
||||||
|
int num_waiting() const {
|
||||||
|
return waiting_threads.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GuardType guard_object = {};
|
||||||
|
std::atomic<int> waiting_threads{0};
|
||||||
|
std::array<std::atomic<int>, 4> result_counts{};
|
||||||
|
static_assert(static_cast<int>(ABORTED) == 3, "only 4 result kinds expected");
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ThreadGroup {
|
||||||
|
ThreadGroup() = default;
|
||||||
|
ThreadGroup(ThreadGroup const&) = delete;
|
||||||
|
|
||||||
|
template <class ...Args>
|
||||||
|
void Create(Args&& ...args) {
|
||||||
|
threads.emplace_back(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Callback>
|
||||||
|
void CreateThreadsWithBarrier(int N, Callback cb) {
|
||||||
|
auto start = std::make_shared<Barrier>(N + 1);
|
||||||
|
for (int I=0; I < N; ++I) {
|
||||||
|
Create([start, cb]() {
|
||||||
|
start->arrive_and_wait();
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
start->arrive_and_wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoinAll() {
|
||||||
|
for (auto& t : threads) {
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::thread> threads;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class GuardType, class Impl>
|
||||||
|
void test_free_for_all(int num_waiters) {
|
||||||
|
FunctionLocalStatic<GuardType, Impl> test_obj;
|
||||||
|
|
||||||
|
ThreadGroup threads;
|
||||||
|
|
||||||
|
bool already_init = false;
|
||||||
|
threads.CreateThreadsWithBarrier(num_waiters,
|
||||||
|
test_obj.access_callback([&]() {
|
||||||
|
assert(!already_init);
|
||||||
|
already_init = true;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// wait for the other threads to finish initialization.
|
||||||
|
threads.JoinAll();
|
||||||
|
|
||||||
|
assert(test_obj.get_count(PERFORMED) == 1);
|
||||||
|
assert(test_obj.get_count(COMPLETE) + test_obj.get_count(WAITED) == num_waiters - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class GuardType, class Impl>
|
||||||
|
void test_waiting_for_init(int num_waiters) {
|
||||||
|
FunctionLocalStatic<GuardType, Impl> test_obj;
|
||||||
|
|
||||||
|
ThreadGroup threads;
|
||||||
|
|
||||||
|
Barrier start_init(2);
|
||||||
|
threads.Create(test_obj.access_callback(
|
||||||
|
[&]() {
|
||||||
|
start_init.arrive_and_wait();
|
||||||
|
// Take our sweet time completing the initialization...
|
||||||
|
//
|
||||||
|
// There's a race condition between the other threads reaching the
|
||||||
|
// start_init barrier, and them actually hitting the cxa guard.
|
||||||
|
// But we're trying to test the waiting logic, we want as many
|
||||||
|
// threads to enter the waiting loop as possible.
|
||||||
|
YieldAfterBarrier();
|
||||||
|
}
|
||||||
|
));
|
||||||
|
start_init.wait_for_threads(1);
|
||||||
|
|
||||||
|
threads.CreateThreadsWithBarrier(num_waiters,
|
||||||
|
test_obj.access_callback([]() { assert(false); })
|
||||||
|
);
|
||||||
|
// unblock the initializing thread
|
||||||
|
start_init.arrive_and_drop();
|
||||||
|
|
||||||
|
// wait for the other threads to finish initialization.
|
||||||
|
threads.JoinAll();
|
||||||
|
|
||||||
|
assert(test_obj.get_count(PERFORMED) == 1);
|
||||||
|
assert(test_obj.get_count(ABORTED) == 0);
|
||||||
|
assert(test_obj.get_count(COMPLETE) + test_obj.get_count(WAITED) == num_waiters);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class GuardType, class Impl>
|
||||||
|
void test_aborted_init(int num_waiters) {
|
||||||
|
FunctionLocalStatic<GuardType, Impl> test_obj;
|
||||||
|
|
||||||
|
Barrier start_init(2);
|
||||||
|
ThreadGroup threads;
|
||||||
|
threads.Create(test_obj.access_callback(
|
||||||
|
[&]() {
|
||||||
|
start_init.arrive_and_wait();
|
||||||
|
YieldAfterBarrier();
|
||||||
|
throw 42;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
start_init.wait_for_threads(1);
|
||||||
|
|
||||||
|
bool already_init = false;
|
||||||
|
threads.CreateThreadsWithBarrier(num_waiters,
|
||||||
|
test_obj.access_callback([&]() {
|
||||||
|
assert(!already_init);
|
||||||
|
already_init = true;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
// unblock the initializing thread
|
||||||
|
start_init.arrive_and_drop();
|
||||||
|
|
||||||
|
// wait for the other threads to finish initialization.
|
||||||
|
threads.JoinAll();
|
||||||
|
|
||||||
|
assert(test_obj.get_count(ABORTED) == 1);
|
||||||
|
assert(test_obj.get_count(PERFORMED) == 1);
|
||||||
|
assert(test_obj.get_count(WAITED) + test_obj.get_count(COMPLETE) == num_waiters - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class GuardType, class Impl>
|
||||||
|
void test_completed_init(int num_waiters) {
|
||||||
|
|
||||||
|
FunctionLocalStatic<GuardType, Impl> test_obj;
|
||||||
|
|
||||||
|
test_obj.access([]() {}); // initialize the object
|
||||||
|
assert(test_obj.num_waiting() == 0);
|
||||||
|
assert(test_obj.num_completed() == 1);
|
||||||
|
assert(test_obj.get_count(PERFORMED) == 1);
|
||||||
|
|
||||||
|
ThreadGroup threads;
|
||||||
|
threads.CreateThreadsWithBarrier(num_waiters,
|
||||||
|
test_obj.access_callback([]() { assert(false); })
|
||||||
|
);
|
||||||
|
// wait for the other threads to finish initialization.
|
||||||
|
threads.JoinAll();
|
||||||
|
|
||||||
|
assert(test_obj.get_count(ABORTED) == 0);
|
||||||
|
assert(test_obj.get_count(PERFORMED) == 1);
|
||||||
|
assert(test_obj.get_count(WAITED) == 0);
|
||||||
|
assert(test_obj.get_count(COMPLETE) == num_waiters);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Impl>
|
||||||
|
void test_impl() {
|
||||||
|
using TestFn = void(*)(int);
|
||||||
|
TestFn TestList[] = {
|
||||||
|
test_free_for_all<uint32_t, Impl>,
|
||||||
|
test_free_for_all<uint32_t, Impl>,
|
||||||
|
test_waiting_for_init<uint32_t, Impl>,
|
||||||
|
test_waiting_for_init<uint64_t, Impl>,
|
||||||
|
test_aborted_init<uint32_t, Impl>,
|
||||||
|
test_aborted_init<uint64_t, Impl>,
|
||||||
|
test_completed_init<uint32_t, Impl>,
|
||||||
|
test_completed_init<uint64_t, Impl>
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto test_func : TestList) {
|
||||||
|
ThreadGroup test_threads;
|
||||||
|
test_threads.CreateThreadsWithBarrier(ConcurrentRunsPerTest, [=]() {
|
||||||
|
for (int I = 0; I < TestSamples; ++I) {
|
||||||
|
test_func(ThreadsPerTest);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
test_threads.JoinAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_all_impls() {
|
||||||
|
using MutexImpl = SelectImplementation<Implementation::GlobalMutex>::type;
|
||||||
|
|
||||||
|
// Attempt to test the Futex based implementation if it's supported on the
|
||||||
|
// target platform.
|
||||||
|
using RealFutexImpl = SelectImplementation<Implementation::Futex>::type;
|
||||||
|
using FutexImpl = typename std::conditional<
|
||||||
|
PlatformSupportsFutex(),
|
||||||
|
RealFutexImpl,
|
||||||
|
MutexImpl
|
||||||
|
>::type;
|
||||||
|
|
||||||
|
test_impl<MutexImpl>();
|
||||||
|
if (PlatformSupportsFutex())
|
||||||
|
test_impl<FutexImpl>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// A dummy
|
||||||
|
template <bool Dummy = true>
|
||||||
|
void test_futex_syscall() {
|
||||||
|
if (!PlatformSupportsFutex())
|
||||||
|
return;
|
||||||
|
int lock1 = 0;
|
||||||
|
int lock2 = 0;
|
||||||
|
int lock3 = 0;
|
||||||
|
std::thread waiter1 = support::make_test_thread([&]() {
|
||||||
|
int expect = 0;
|
||||||
|
PlatformFutexWait(&lock1, expect);
|
||||||
|
assert(lock1 == 1);
|
||||||
|
});
|
||||||
|
std::thread waiter2 = support::make_test_thread([&]() {
|
||||||
|
int expect = 0;
|
||||||
|
PlatformFutexWait(&lock2, expect);
|
||||||
|
assert(lock2 == 2);
|
||||||
|
});
|
||||||
|
std::thread waiter3 = support::make_test_thread([&]() {
|
||||||
|
int expect = 42; // not the value
|
||||||
|
PlatformFutexWait(&lock3, expect); // doesn't block
|
||||||
|
});
|
||||||
|
std::thread waker = support::make_test_thread([&]() {
|
||||||
|
lock1 = 1;
|
||||||
|
PlatformFutexWake(&lock1);
|
||||||
|
lock2 = 2;
|
||||||
|
PlatformFutexWake(&lock2);
|
||||||
|
});
|
||||||
|
waiter1.join();
|
||||||
|
waiter2.join();
|
||||||
|
waiter3.join();
|
||||||
|
waker.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
// Test each multi-threaded implementation with real threads.
|
||||||
|
test_all_impls();
|
||||||
|
// Test the basic sanity of the futex syscall wrappers.
|
||||||
|
test_futex_syscall();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
211
third_party/libcxxabi/test/incomplete_type.sh.cc
vendored
Normal file
211
third_party/libcxxabi/test/incomplete_type.sh.cc
vendored
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#rtti-layout
|
||||||
|
|
||||||
|
// Two abi::__pbase_type_info objects can always be compared for equality
|
||||||
|
// (i.e. of the types represented) or ordering by comparison of their name
|
||||||
|
// NTBS addresses. In addition, unless either or both have either of the
|
||||||
|
// incomplete flags set, equality can be tested by comparing the type_info
|
||||||
|
// addresses.
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
// UNSUPPORTED: no-rtti
|
||||||
|
|
||||||
|
// The fix for PR25898 landed in the system dylibs in macOS 10.13
|
||||||
|
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{9|10|11|12}}
|
||||||
|
|
||||||
|
// RUN: %{cxx} %{flags} %{compile_flags} -Wno-unreachable-code -c %s -o %t.one.o
|
||||||
|
// RUN: %{cxx} %{flags} %{compile_flags} -Wno-unreachable-code -c %s -o %t.two.o -DTU_ONE
|
||||||
|
// RUN: %{cxx} %{flags} %t.one.o %t.two.o %{link_flags} -o %t.exe
|
||||||
|
// RUN: %{exec} %t.exe
|
||||||
|
|
||||||
|
#include "libc/stdio/stdio.h"
|
||||||
|
#include "third_party/libcxx/cstring"
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
#include "third_party/libcxx/typeinfo"
|
||||||
|
|
||||||
|
// Check that the addresses of the typeinfo differ but still compare equal
|
||||||
|
// via their NTBS.
|
||||||
|
inline void
|
||||||
|
AssertIncompleteTypeInfoEquals(std::type_info const& LHS, std::type_info const& RHS)
|
||||||
|
{
|
||||||
|
assert(&LHS != &RHS);
|
||||||
|
assert(strcmp(LHS.name(), RHS.name()) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NeverDefined;
|
||||||
|
void ThrowNeverDefinedMP();
|
||||||
|
std::type_info const& ReturnTypeInfoNeverDefinedMP();
|
||||||
|
|
||||||
|
struct IncompleteAtThrow;
|
||||||
|
void ThrowIncompleteMP();
|
||||||
|
void ThrowIncompletePP();
|
||||||
|
void ThrowIncompletePMP();
|
||||||
|
std::type_info const& ReturnTypeInfoIncompleteMP();
|
||||||
|
std::type_info const& ReturnTypeInfoIncompletePP();
|
||||||
|
|
||||||
|
struct CompleteAtThrow;
|
||||||
|
void ThrowCompleteMP();
|
||||||
|
void ThrowCompletePP();
|
||||||
|
void ThrowCompletePMP();
|
||||||
|
std::type_info const& ReturnTypeInfoCompleteMP();
|
||||||
|
std::type_info const& ReturnTypeInfoCompletePP();
|
||||||
|
|
||||||
|
void ThrowNullptr();
|
||||||
|
|
||||||
|
#ifndef TU_ONE
|
||||||
|
|
||||||
|
void ThrowNeverDefinedMP() { throw (int NeverDefined::*)nullptr; }
|
||||||
|
std::type_info const& ReturnTypeInfoNeverDefinedMP() { return typeid(int NeverDefined::*); }
|
||||||
|
|
||||||
|
void ThrowIncompleteMP() { throw (int IncompleteAtThrow::*)nullptr; }
|
||||||
|
void ThrowIncompletePP() { throw (IncompleteAtThrow**)nullptr; }
|
||||||
|
void ThrowIncompletePMP() { throw (int IncompleteAtThrow::**)nullptr; }
|
||||||
|
std::type_info const& ReturnTypeInfoIncompleteMP() { return typeid(int IncompleteAtThrow::*); }
|
||||||
|
std::type_info const& ReturnTypeInfoIncompletePP() { return typeid(IncompleteAtThrow**); }
|
||||||
|
|
||||||
|
struct CompleteAtThrow {};
|
||||||
|
void ThrowCompleteMP() { throw (int CompleteAtThrow::*)nullptr; }
|
||||||
|
void ThrowCompletePP() { throw (CompleteAtThrow**)nullptr; }
|
||||||
|
void ThrowCompletePMP() { throw (int CompleteAtThrow::**)nullptr; }
|
||||||
|
std::type_info const& ReturnTypeInfoCompleteMP() { return typeid(int CompleteAtThrow::*); }
|
||||||
|
std::type_info const& ReturnTypeInfoCompletePP() { return typeid(CompleteAtThrow**); }
|
||||||
|
|
||||||
|
void ThrowNullptr() { throw nullptr; }
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
struct IncompleteAtThrow {};
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
AssertIncompleteTypeInfoEquals(ReturnTypeInfoNeverDefinedMP(), typeid(int NeverDefined::*));
|
||||||
|
try {
|
||||||
|
ThrowNeverDefinedMP();
|
||||||
|
assert(false);
|
||||||
|
} catch (int IncompleteAtThrow::*) {
|
||||||
|
assert(false);
|
||||||
|
} catch (int CompleteAtThrow::*) {
|
||||||
|
assert(false);
|
||||||
|
} catch (int NeverDefined::*p) {
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch(...) { assert(!"FAIL: Didn't catch NeverDefined::*" ); }
|
||||||
|
|
||||||
|
AssertIncompleteTypeInfoEquals(ReturnTypeInfoIncompleteMP(), typeid(int IncompleteAtThrow::*));
|
||||||
|
try {
|
||||||
|
ThrowIncompleteMP();
|
||||||
|
assert(false);
|
||||||
|
} catch (CompleteAtThrow**) {
|
||||||
|
assert(false);
|
||||||
|
} catch (int CompleteAtThrow::*) {
|
||||||
|
assert(false);
|
||||||
|
} catch (IncompleteAtThrow**) {
|
||||||
|
assert(false);
|
||||||
|
} catch (int IncompleteAtThrow::*p) {
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch(...) { assert(!"FAIL: Didn't catch IncompleteAtThrow::*" ); }
|
||||||
|
|
||||||
|
AssertIncompleteTypeInfoEquals(ReturnTypeInfoIncompletePP(), typeid(IncompleteAtThrow**));
|
||||||
|
try {
|
||||||
|
ThrowIncompletePP();
|
||||||
|
assert(false);
|
||||||
|
} catch (int IncompleteAtThrow::*) {
|
||||||
|
assert(false);
|
||||||
|
} catch (IncompleteAtThrow** p) {
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch(...) { assert(!"FAIL: Didn't catch IncompleteAtThrow**" ); }
|
||||||
|
|
||||||
|
try {
|
||||||
|
ThrowIncompletePMP();
|
||||||
|
assert(false);
|
||||||
|
} catch (int IncompleteAtThrow::*) {
|
||||||
|
assert(false);
|
||||||
|
} catch (IncompleteAtThrow**) {
|
||||||
|
assert(false);
|
||||||
|
} catch (int IncompleteAtThrow::**p) {
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch(...) { assert(!"FAIL: Didn't catch IncompleteAtThrow::**" ); }
|
||||||
|
|
||||||
|
AssertIncompleteTypeInfoEquals(ReturnTypeInfoCompleteMP(), typeid(int CompleteAtThrow::*));
|
||||||
|
try {
|
||||||
|
ThrowCompleteMP();
|
||||||
|
assert(false);
|
||||||
|
} catch (IncompleteAtThrow**) {
|
||||||
|
assert(false);
|
||||||
|
} catch (int IncompleteAtThrow::*) {
|
||||||
|
assert(false);
|
||||||
|
} catch (CompleteAtThrow**) {
|
||||||
|
assert(false);
|
||||||
|
} catch (int CompleteAtThrow::*p) {
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch(...) { assert(!"FAIL: Didn't catch CompleteAtThrow::" ); }
|
||||||
|
|
||||||
|
AssertIncompleteTypeInfoEquals(ReturnTypeInfoCompletePP(), typeid(CompleteAtThrow**));
|
||||||
|
try {
|
||||||
|
ThrowCompletePP();
|
||||||
|
assert(false);
|
||||||
|
} catch (IncompleteAtThrow**) {
|
||||||
|
assert(false);
|
||||||
|
} catch (int IncompleteAtThrow::*) {
|
||||||
|
assert(false);
|
||||||
|
} catch (int CompleteAtThrow::*) {
|
||||||
|
assert(false);
|
||||||
|
} catch (CompleteAtThrow**p) {
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch(...) { assert(!"FAIL: Didn't catch CompleteAtThrow**" ); }
|
||||||
|
|
||||||
|
try {
|
||||||
|
ThrowCompletePMP();
|
||||||
|
assert(false);
|
||||||
|
} catch (IncompleteAtThrow**) {
|
||||||
|
assert(false);
|
||||||
|
} catch (int IncompleteAtThrow::*) {
|
||||||
|
assert(false);
|
||||||
|
} catch (int CompleteAtThrow::*) {
|
||||||
|
assert(false);
|
||||||
|
} catch (CompleteAtThrow**) {
|
||||||
|
assert(false);
|
||||||
|
} catch (int CompleteAtThrow::**p) {
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch(...) { assert(!"FAIL: Didn't catch CompleteAtThrow::**" ); }
|
||||||
|
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
// Catch nullptr as complete type
|
||||||
|
try {
|
||||||
|
ThrowNullptr();
|
||||||
|
} catch (int IncompleteAtThrow::*p) {
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch(...) { assert(!"FAIL: Didn't catch nullptr as IncompleteAtThrow::*" ); }
|
||||||
|
|
||||||
|
// Catch nullptr as an incomplete type
|
||||||
|
try {
|
||||||
|
ThrowNullptr();
|
||||||
|
} catch (int CompleteAtThrow::*p) {
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch(...) { assert(!"FAIL: Didn't catch nullptr as CompleteAtThrow::*" ); }
|
||||||
|
|
||||||
|
// Catch nullptr as a type that is never complete.
|
||||||
|
try {
|
||||||
|
ThrowNullptr();
|
||||||
|
} catch (int NeverDefined::*p) {
|
||||||
|
assert(!p);
|
||||||
|
}
|
||||||
|
catch(...) { assert(!"FAIL: Didn't catch nullptr as NeverDefined::*" ); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
1
third_party/libcxxabi/test/incomplete_type.sh.one.cc
vendored
Symbolic link
1
third_party/libcxxabi/test/incomplete_type.sh.one.cc
vendored
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
incomplete_type.sh.cc
|
1
third_party/libcxxabi/test/incomplete_type.sh.two.cc
vendored
Symbolic link
1
third_party/libcxxabi/test/incomplete_type.sh.two.cc
vendored
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
incomplete_type.sh.cc
|
173
third_party/libcxxabi/test/inherited_exception.pass.cc
vendored
Normal file
173
third_party/libcxxabi/test/inherited_exception.pass.cc
vendored
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This test case checks specifically the cases under C++ ABI 15.3.1, and 15.3.2
|
||||||
|
//
|
||||||
|
// C++ ABI 15.3:
|
||||||
|
// A handler is a match for an exception object of type E if
|
||||||
|
// > * The handler is of type cv T or cv T& and E and T are the same type <
|
||||||
|
// > (ignoring the top-level cv-qualifiers), or <
|
||||||
|
// > * the handler is of type cv T or cv T& and T is an unambiguous base <
|
||||||
|
// > class of E, or <
|
||||||
|
// * the handler is of type cv1 T* cv2 and E is a pointer type that can
|
||||||
|
// be converted to the type of the handler by either or both of
|
||||||
|
// o a standard pointer conversion (4.10 [conv.ptr]) not involving
|
||||||
|
// conversions to private or protected or ambiguous classes
|
||||||
|
// o a qualification conversion
|
||||||
|
// * the handler is a pointer or pointer to member type and E is
|
||||||
|
// std::nullptr_t
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
// Compilers emit warnings about exceptions of type 'Child' being caught by
|
||||||
|
// an earlier handler of type 'Base'. Congrats, you've just diagnosed the
|
||||||
|
// behavior under test.
|
||||||
|
// ADDITIONAL_COMPILE_FLAGS: -Wno-exceptions
|
||||||
|
|
||||||
|
#include "libc/isystem/assert.h"
|
||||||
|
|
||||||
|
struct Base {
|
||||||
|
int b1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Base2 {
|
||||||
|
int b2;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Child : public Base, public Base2 {
|
||||||
|
int c;
|
||||||
|
};
|
||||||
|
|
||||||
|
void f1() {
|
||||||
|
Child child;
|
||||||
|
child.b1 = 10;
|
||||||
|
child.b2 = 11;
|
||||||
|
child.c = 12;
|
||||||
|
throw child;
|
||||||
|
}
|
||||||
|
|
||||||
|
void f2() {
|
||||||
|
Child child;
|
||||||
|
child.b1 = 10;
|
||||||
|
child.b2 = 11;
|
||||||
|
child.c = 12;
|
||||||
|
throw static_cast<Base2&>(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
void f3() {
|
||||||
|
static Child child;
|
||||||
|
child.b1 = 10;
|
||||||
|
child.b2 = 11;
|
||||||
|
child.c = 12;
|
||||||
|
throw static_cast<Base2*>(&child);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f1();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const Child& c)
|
||||||
|
{
|
||||||
|
assert(true);
|
||||||
|
}
|
||||||
|
catch (const Base& b)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f1();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const Base& c)
|
||||||
|
{
|
||||||
|
assert(true);
|
||||||
|
}
|
||||||
|
catch (const Child& b)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f1();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const Base2& c)
|
||||||
|
{
|
||||||
|
assert(true);
|
||||||
|
}
|
||||||
|
catch (const Child& b)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f2();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const Child& c)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const Base& b)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const Base2& b)
|
||||||
|
{
|
||||||
|
assert(true);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f3();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const Base* c)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const Child* b)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const Base2* c)
|
||||||
|
{
|
||||||
|
assert(true);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
54
third_party/libcxxabi/test/support/timer.hh
vendored
Normal file
54
third_party/libcxxabi/test/support/timer.hh
vendored
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
//===----------------------------------------------------------------------===////
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===////
|
||||||
|
|
||||||
|
#ifndef TIMER_H
|
||||||
|
#define TIMER_H
|
||||||
|
|
||||||
|
// Define LIBCXXABI_USE_TIMER to enable testing with a timer.
|
||||||
|
#if defined(LIBCXXABI_USE_TIMER)
|
||||||
|
|
||||||
|
#include "third_party/libcxx/chrono"
|
||||||
|
#include "third_party/libcxx/cstdio"
|
||||||
|
|
||||||
|
class timer
|
||||||
|
{
|
||||||
|
typedef std::chrono::high_resolution_clock Clock;
|
||||||
|
typedef Clock::time_point TimePoint;
|
||||||
|
typedef std::chrono::microseconds MicroSeconds;
|
||||||
|
public:
|
||||||
|
timer() : m_start(Clock::now()) {}
|
||||||
|
|
||||||
|
timer(timer const &) = delete;
|
||||||
|
timer & operator=(timer const &) = delete;
|
||||||
|
|
||||||
|
~timer()
|
||||||
|
{
|
||||||
|
using std::chrono::duration_cast;
|
||||||
|
TimePoint end = Clock::now();
|
||||||
|
MicroSeconds us = duration_cast<MicroSeconds>(end - m_start);
|
||||||
|
std::printf("%d microseconds\n", us.count());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TimePoint m_start;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* LIBCXXABI_USE_TIMER */
|
||||||
|
|
||||||
|
class timer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
timer() {}
|
||||||
|
timer(timer const &) = delete;
|
||||||
|
timer & operator=(timer const &) = delete;
|
||||||
|
~timer() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* LIBCXXABI_USE_TIMER */
|
||||||
|
|
||||||
|
#endif /* TIMER_H */
|
62
third_party/libcxxabi/test/test_aux_runtime.pass.cc
vendored
Normal file
62
third_party/libcxxabi/test/test_aux_runtime.pass.cc
vendored
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
#include "third_party/libcxx/typeinfo"
|
||||||
|
|
||||||
|
// Test taken from 5.2.8.2
|
||||||
|
// When typeid is applied to a glvalue expression whose type is a polymorphic
|
||||||
|
// class type, (10.3), the result refers to a std::type_info object
|
||||||
|
// representing the type of the most derived object (1.8) (that is, the
|
||||||
|
// dynamic type) to which the glvalue refers. If the glvalue expression is
|
||||||
|
// obtained by applying the unary * operator to a pointer(68) and the pointer
|
||||||
|
// is a null pointer value (4.10), the typeid expression throws the
|
||||||
|
// std::bad_typeid exception (18.7.3).
|
||||||
|
//
|
||||||
|
// 68) If p is an expression of pointer type, then *p, (*p), *(p),
|
||||||
|
// ((*p)), *((p)), and so on all meet this requirement.
|
||||||
|
bool bad_typeid_test () {
|
||||||
|
class A { virtual void f() {}};
|
||||||
|
class B { virtual void g() {}};
|
||||||
|
|
||||||
|
B *bp = NULL;
|
||||||
|
try {bool b = typeid(*bp) == typeid (A); ((void)b); }
|
||||||
|
catch ( const std::bad_typeid &) { return true; }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// The value of a failed cast to pointer type is the null pointer value of
|
||||||
|
// the required result type. A failed cast to reference type throws
|
||||||
|
// std::bad_cast (18.7.2).
|
||||||
|
bool bad_cast_test () {
|
||||||
|
class A { virtual void f() {}};
|
||||||
|
class B { virtual void g() {}};
|
||||||
|
class D : public virtual A, private B {};
|
||||||
|
|
||||||
|
D d;
|
||||||
|
B *bp = (B*)&d; // cast needed to break protection
|
||||||
|
try { D &dr = dynamic_cast<D&> (*bp); ((void)dr); }
|
||||||
|
catch ( const std::bad_cast & ) { return true; }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main ( ) {
|
||||||
|
int ret_val = 0;
|
||||||
|
|
||||||
|
if ( !bad_typeid_test ()) {
|
||||||
|
ret_val = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !bad_cast_test ()) {
|
||||||
|
ret_val = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_val;
|
||||||
|
}
|
42
third_party/libcxxabi/test/test_aux_runtime_op_array_new.pass.cc
vendored
Normal file
42
third_party/libcxxabi/test/test_aux_runtime_op_array_new.pass.cc
vendored
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
// ___cxa_throw_bad_array_new_length is re-exported from libc++ only starting
|
||||||
|
// in macosx 10.15
|
||||||
|
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14}}
|
||||||
|
|
||||||
|
#include "third_party/libcxxabi/include/cxxabi.h"
|
||||||
|
#include "third_party/libcxx/new"
|
||||||
|
|
||||||
|
// If the expression passed to operator new[] would result in an overflow, the
|
||||||
|
// allocation function is not called, and a std::bad_array_new_length exception
|
||||||
|
// is thrown instead (5.3.4p7).
|
||||||
|
bool bad_array_new_length_test() {
|
||||||
|
try {
|
||||||
|
// We test this directly because Clang does not currently codegen the
|
||||||
|
// correct call to __cxa_bad_array_new_length, so this test would result
|
||||||
|
// in passing -1 to ::operator new[], which would then throw a
|
||||||
|
// std::bad_alloc, causing the test to fail.
|
||||||
|
__cxxabiv1::__cxa_throw_bad_array_new_length();
|
||||||
|
} catch ( const std::bad_array_new_length &banl ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
int ret_val = 0;
|
||||||
|
|
||||||
|
if ( !bad_array_new_length_test ()) {
|
||||||
|
ret_val = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_val;
|
||||||
|
}
|
30373
third_party/libcxxabi/test/test_demangle.pass.cc
vendored
Normal file
30373
third_party/libcxxabi/test/test_demangle.pass.cc
vendored
Normal file
File diff suppressed because one or more lines are too long
53
third_party/libcxxabi/test/test_exception_address_alignment.pass.cc
vendored
Normal file
53
third_party/libcxxabi/test/test_exception_address_alignment.pass.cc
vendored
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
// UNSUPPORTED: c++03
|
||||||
|
|
||||||
|
// The <unwind.h> header provided in the SDK of older Xcodes used to provide
|
||||||
|
// an incorrectly aligned _Unwind_Exception type on non-ARM. That causes these
|
||||||
|
// tests to fail when running against a system libc++abi and libunwind that was
|
||||||
|
// compiled with an incorrect definition of _Unwind_Exception.
|
||||||
|
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{9|10|11|12}}
|
||||||
|
|
||||||
|
// Test that the address of the exception object is properly aligned as required
|
||||||
|
// by the relevant ABI
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cstdint"
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
#include "third_party/libcxxabi/include/__cxxabi_config.h"
|
||||||
|
|
||||||
|
#include "third_party/libunwind/include/unwind.h"
|
||||||
|
|
||||||
|
struct __attribute__((aligned)) AlignedType {};
|
||||||
|
|
||||||
|
// EHABI : 8-byte aligned
|
||||||
|
// Itanium: Largest supported alignment for the system
|
||||||
|
#if defined(_LIBCXXABI_ARM_EHABI)
|
||||||
|
# define EXPECTED_ALIGNMENT 8
|
||||||
|
#else
|
||||||
|
# define EXPECTED_ALIGNMENT alignof(AlignedType)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static_assert(alignof(_Unwind_Exception) == EXPECTED_ALIGNMENT,
|
||||||
|
"_Unwind_Exception is incorrectly aligned. This test is expected to fail");
|
||||||
|
|
||||||
|
struct MinAligned { };
|
||||||
|
static_assert(alignof(MinAligned) == 1 && sizeof(MinAligned) == 1, "");
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
for (int i=0; i < 10; ++i) {
|
||||||
|
try {
|
||||||
|
throw MinAligned{};
|
||||||
|
} catch (MinAligned const& ref) {
|
||||||
|
assert(reinterpret_cast<uintptr_t>(&ref) % EXPECTED_ALIGNMENT == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
76
third_party/libcxxabi/test/test_exception_storage.pass.cc
vendored
Normal file
76
third_party/libcxxabi/test/test_exception_storage.pass.cc
vendored
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "third_party/libcxx/algorithm"
|
||||||
|
#include "third_party/libcxx/cstdio"
|
||||||
|
#include "third_party/libcxx/cstdlib"
|
||||||
|
#include "third_party/libcxx/__threading_support"
|
||||||
|
#include "libc/isystem/unistd.h"
|
||||||
|
|
||||||
|
#include "third_party/libcxxabi/cxa_exception.h"
|
||||||
|
|
||||||
|
#include "third_party/libcxxabi/libcxx/test/support/test_macros.hh"
|
||||||
|
|
||||||
|
typedef __cxxabiv1::__cxa_eh_globals globals_t ;
|
||||||
|
|
||||||
|
void *thread_code (void *parm) {
|
||||||
|
size_t *result = (size_t *) parm;
|
||||||
|
globals_t *glob1, *glob2;
|
||||||
|
|
||||||
|
glob1 = __cxxabiv1::__cxa_get_globals ();
|
||||||
|
if ( NULL == glob1 )
|
||||||
|
std::printf("Got null result from __cxa_get_globals\n");
|
||||||
|
|
||||||
|
glob2 = __cxxabiv1::__cxa_get_globals_fast ();
|
||||||
|
if ( glob1 != glob2 )
|
||||||
|
std::printf("Got different globals!\n");
|
||||||
|
|
||||||
|
*result = (size_t) glob1;
|
||||||
|
#ifndef TEST_HAS_NO_THREADS
|
||||||
|
sleep ( 1 );
|
||||||
|
#endif
|
||||||
|
return parm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef TEST_HAS_NO_THREADS
|
||||||
|
#define NUMTHREADS 10
|
||||||
|
size_t thread_globals [ NUMTHREADS ] = { 0 };
|
||||||
|
std::__libcpp_thread_t threads [ NUMTHREADS ];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#ifndef TEST_HAS_NO_THREADS
|
||||||
|
// Make the threads, let them run, and wait for them to finish
|
||||||
|
for ( int i = 0; i < NUMTHREADS; ++i )
|
||||||
|
std::__libcpp_thread_create ( threads + i, thread_code, (void *) (thread_globals + i));
|
||||||
|
for ( int i = 0; i < NUMTHREADS; ++i )
|
||||||
|
std::__libcpp_thread_join ( &threads [ i ] );
|
||||||
|
|
||||||
|
int retVal = 0;
|
||||||
|
for ( int i = 0; i < NUMTHREADS; ++i ) {
|
||||||
|
if ( 0 == thread_globals [ i ] ) {
|
||||||
|
std::printf("Thread #%d had a zero global\n", i);
|
||||||
|
retVal = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort ( thread_globals, thread_globals + NUMTHREADS );
|
||||||
|
for ( int i = 1; i < NUMTHREADS; ++i ) {
|
||||||
|
if ( thread_globals [ i - 1 ] == thread_globals [ i ] ) {
|
||||||
|
std::printf("Duplicate thread globals (%d and %d)\n", i-1, i);
|
||||||
|
retVal = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
#else // TEST_HAS_NO_THREADS
|
||||||
|
size_t thread_globals;
|
||||||
|
thread_code(&thread_globals);
|
||||||
|
// Check that __cxa_get_globals() is not NULL.
|
||||||
|
return (thread_globals == 0) ? 1 : 0;
|
||||||
|
#endif // !TEST_HAS_NO_THREADS
|
||||||
|
}
|
212
third_party/libcxxabi/test/test_fallback_malloc.pass.cc
vendored
Normal file
212
third_party/libcxxabi/test/test_fallback_malloc.pass.cc
vendored
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cstdio"
|
||||||
|
#include "third_party/libcxx/deque"
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
#include "libc/isystem/inttypes.h"
|
||||||
|
|
||||||
|
#include "third_party/libcxx/__threading_support"
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++03
|
||||||
|
// UNSUPPORTED: modules-build && no-threads
|
||||||
|
|
||||||
|
// Necessary because we include a private source file of libc++abi, which
|
||||||
|
// only understands _LIBCXXABI_HAS_NO_THREADS.
|
||||||
|
#include "third_party/libcxxabi/libcxx/test/support/test_macros.hh"
|
||||||
|
#ifdef TEST_HAS_NO_THREADS
|
||||||
|
# define _LIBCXXABI_HAS_NO_THREADS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef std::deque<void *> container;
|
||||||
|
|
||||||
|
TEST_DIAGNOSTIC_PUSH
|
||||||
|
TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header")
|
||||||
|
// #define DEBUG_FALLBACK_MALLOC
|
||||||
|
#define INSTRUMENT_FALLBACK_MALLOC
|
||||||
|
#include "third_party/libcxxabi/fallback_malloc.cc"
|
||||||
|
TEST_DIAGNOSTIC_POP
|
||||||
|
|
||||||
|
void assertAlignment(void* ptr) { assert(reinterpret_cast<size_t>(ptr) % alignof(FallbackMaxAlignType) == 0); }
|
||||||
|
|
||||||
|
container alloc_series ( size_t sz ) {
|
||||||
|
container ptrs;
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
while (NULL != (p = fallback_malloc(sz))) {
|
||||||
|
assertAlignment(p);
|
||||||
|
ptrs.push_back(p);
|
||||||
|
}
|
||||||
|
return ptrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
container alloc_series ( size_t sz, float growth ) {
|
||||||
|
container ptrs;
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
while ( NULL != ( p = fallback_malloc ( sz ))) {
|
||||||
|
assertAlignment(p);
|
||||||
|
ptrs.push_back(p);
|
||||||
|
sz *= growth;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
container alloc_series ( const size_t *first, size_t len ) {
|
||||||
|
container ptrs;
|
||||||
|
const size_t *last = first + len;
|
||||||
|
void * p;
|
||||||
|
|
||||||
|
for ( const size_t *iter = first; iter != last; ++iter ) {
|
||||||
|
if ( NULL == (p = fallback_malloc ( *iter )))
|
||||||
|
break;
|
||||||
|
assertAlignment(p);
|
||||||
|
ptrs.push_back ( p );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *pop ( container &c, bool from_end ) {
|
||||||
|
void *ptr;
|
||||||
|
if ( from_end ) {
|
||||||
|
ptr = c.back ();
|
||||||
|
c.pop_back ();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ptr = c.front ();
|
||||||
|
c.pop_front ();
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void exhaustion_test1 () {
|
||||||
|
container ptrs;
|
||||||
|
|
||||||
|
init_heap ();
|
||||||
|
std::printf("Constant exhaustion tests\n");
|
||||||
|
|
||||||
|
// Delete in allocation order
|
||||||
|
ptrs = alloc_series ( 32 );
|
||||||
|
std::printf("Allocated %zu 32 byte chunks\n", ptrs.size());
|
||||||
|
print_free_list ();
|
||||||
|
for ( container::iterator iter = ptrs.begin (); iter != ptrs.end (); ++iter )
|
||||||
|
fallback_free ( *iter );
|
||||||
|
print_free_list ();
|
||||||
|
std::printf("----\n");
|
||||||
|
|
||||||
|
// Delete in reverse order
|
||||||
|
ptrs = alloc_series ( 32 );
|
||||||
|
std::printf("Allocated %zu 32 byte chunks\n", ptrs.size());
|
||||||
|
for ( container::reverse_iterator iter = ptrs.rbegin (); iter != ptrs.rend (); ++iter )
|
||||||
|
fallback_free ( *iter );
|
||||||
|
print_free_list ();
|
||||||
|
std::printf("----\n");
|
||||||
|
|
||||||
|
// Alternate deletions
|
||||||
|
ptrs = alloc_series ( 32 );
|
||||||
|
std::printf("Allocated %zu 32 byte chunks\n", ptrs.size());
|
||||||
|
while ( ptrs.size () > 0 )
|
||||||
|
fallback_free ( pop ( ptrs, ptrs.size () % 1 == 1 ));
|
||||||
|
print_free_list ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void exhaustion_test2 () {
|
||||||
|
container ptrs;
|
||||||
|
init_heap ();
|
||||||
|
|
||||||
|
std::printf("Growing exhaustion tests\n");
|
||||||
|
|
||||||
|
// Delete in allocation order
|
||||||
|
ptrs = alloc_series ( 32, 1.5 );
|
||||||
|
|
||||||
|
std::printf("Allocated %zu { 32, 48, 72, 108, 162 ... } byte chunks\n",
|
||||||
|
ptrs.size());
|
||||||
|
print_free_list ();
|
||||||
|
for ( container::iterator iter = ptrs.begin (); iter != ptrs.end (); ++iter )
|
||||||
|
fallback_free ( *iter );
|
||||||
|
print_free_list ();
|
||||||
|
std::printf("----\n");
|
||||||
|
|
||||||
|
// Delete in reverse order
|
||||||
|
print_free_list ();
|
||||||
|
ptrs = alloc_series ( 32, 1.5 );
|
||||||
|
std::printf("Allocated %zu { 32, 48, 72, 108, 162 ... } byte chunks\n",
|
||||||
|
ptrs.size());
|
||||||
|
for ( container::reverse_iterator iter = ptrs.rbegin (); iter != ptrs.rend (); ++iter )
|
||||||
|
fallback_free ( *iter );
|
||||||
|
print_free_list ();
|
||||||
|
std::printf("----\n");
|
||||||
|
|
||||||
|
// Alternate deletions
|
||||||
|
ptrs = alloc_series ( 32, 1.5 );
|
||||||
|
std::printf("Allocated %zu { 32, 48, 72, 108, 162 ... } byte chunks\n",
|
||||||
|
ptrs.size());
|
||||||
|
while ( ptrs.size () > 0 )
|
||||||
|
fallback_free ( pop ( ptrs, ptrs.size () % 1 == 1 ));
|
||||||
|
print_free_list ();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void exhaustion_test3 () {
|
||||||
|
const size_t allocs [] = { 124, 60, 252, 60, 4 };
|
||||||
|
container ptrs;
|
||||||
|
init_heap ();
|
||||||
|
|
||||||
|
std::printf("Complete exhaustion tests\n");
|
||||||
|
|
||||||
|
// Delete in allocation order
|
||||||
|
ptrs = alloc_series ( allocs, sizeof ( allocs ) / sizeof ( allocs[0] ));
|
||||||
|
std::printf("Allocated %zu chunks\n", ptrs.size());
|
||||||
|
print_free_list ();
|
||||||
|
for ( container::iterator iter = ptrs.begin (); iter != ptrs.end (); ++iter )
|
||||||
|
fallback_free ( *iter );
|
||||||
|
print_free_list ();
|
||||||
|
std::printf("----\n");
|
||||||
|
|
||||||
|
// Delete in reverse order
|
||||||
|
print_free_list ();
|
||||||
|
ptrs = alloc_series ( allocs, sizeof ( allocs ) / sizeof ( allocs[0] ));
|
||||||
|
std::printf("Allocated %zu chunks\n", ptrs.size());
|
||||||
|
for ( container::reverse_iterator iter = ptrs.rbegin (); iter != ptrs.rend (); ++iter )
|
||||||
|
fallback_free ( *iter );
|
||||||
|
print_free_list ();
|
||||||
|
std::printf("----\n");
|
||||||
|
|
||||||
|
// Alternate deletions
|
||||||
|
ptrs = alloc_series ( allocs, sizeof ( allocs ) / sizeof ( allocs[0] ));
|
||||||
|
std::printf("Allocated %zu chunks\n", ptrs.size());
|
||||||
|
while ( ptrs.size () > 0 )
|
||||||
|
fallback_free ( pop ( ptrs, ptrs.size () % 1 == 1 ));
|
||||||
|
print_free_list ();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main () {
|
||||||
|
print_free_list ();
|
||||||
|
|
||||||
|
char *p = (char *) fallback_malloc ( 1024 ); // too big!
|
||||||
|
std::printf("fallback_malloc ( 1024 ) --> %" PRIuPTR"\n", (uintptr_t) p);
|
||||||
|
print_free_list ();
|
||||||
|
|
||||||
|
p = (char *) fallback_malloc ( 32 );
|
||||||
|
std::printf("fallback_malloc ( 32 ) --> %" PRIuPTR"\n", (uintptr_t) (p - heap));
|
||||||
|
if ( !is_fallback_ptr ( p ))
|
||||||
|
std::printf("### p is not a fallback pointer!!\n");
|
||||||
|
|
||||||
|
print_free_list ();
|
||||||
|
fallback_free ( p );
|
||||||
|
print_free_list ();
|
||||||
|
|
||||||
|
exhaustion_test1();
|
||||||
|
exhaustion_test2();
|
||||||
|
exhaustion_test3();
|
||||||
|
return 0;
|
||||||
|
}
|
151
third_party/libcxxabi/test/test_guard.pass.cc
vendored
Normal file
151
third_party/libcxxabi/test/test_guard.pass.cc
vendored
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
#include "third_party/libcxxabi/include/cxxabi.h"
|
||||||
|
|
||||||
|
#include "third_party/libcxxabi/libcxx/test/support/test_macros.hh"
|
||||||
|
|
||||||
|
#ifndef TEST_HAS_NO_THREADS
|
||||||
|
# include "third_party/libcxx/thread"
|
||||||
|
# include "third_party/libcxxabi/libcxx/test/support/make_test_thread.hh"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Ensure that we initialize each variable once and only once.
|
||||||
|
namespace test1 {
|
||||||
|
static int run_count = 0;
|
||||||
|
int increment() {
|
||||||
|
++run_count;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
void helper() {
|
||||||
|
static int a = increment();
|
||||||
|
((void)a);
|
||||||
|
}
|
||||||
|
void test() {
|
||||||
|
static int a = increment(); ((void)a);
|
||||||
|
assert(run_count == 1);
|
||||||
|
static int b = increment(); ((void)b);
|
||||||
|
assert(run_count == 2);
|
||||||
|
helper();
|
||||||
|
assert(run_count == 3);
|
||||||
|
helper();
|
||||||
|
assert(run_count == 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// When initialization fails, ensure that we try to initialize it again next
|
||||||
|
// time.
|
||||||
|
namespace test2 {
|
||||||
|
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||||
|
static int run_count = 0;
|
||||||
|
int increment() {
|
||||||
|
++run_count;
|
||||||
|
throw 0;
|
||||||
|
}
|
||||||
|
void helper() {
|
||||||
|
try {
|
||||||
|
static int a = increment();
|
||||||
|
assert(false);
|
||||||
|
((void)a);
|
||||||
|
} catch (...) {}
|
||||||
|
}
|
||||||
|
void test() {
|
||||||
|
helper();
|
||||||
|
assert(run_count == 1);
|
||||||
|
helper();
|
||||||
|
assert(run_count == 2);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void test() {}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that we can initialize a second value while initializing a first.
|
||||||
|
namespace test3 {
|
||||||
|
int zero() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int one() {
|
||||||
|
static int b = zero(); ((void)b);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test() {
|
||||||
|
static int a = one(); ((void)a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef TEST_HAS_NO_THREADS
|
||||||
|
// A simple thread test of two threads racing to initialize a variable. This
|
||||||
|
// isn't guaranteed to catch any particular threading problems.
|
||||||
|
namespace test4 {
|
||||||
|
static int run_count = 0;
|
||||||
|
int increment() {
|
||||||
|
++run_count;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void helper() {
|
||||||
|
static int a = increment(); ((void)a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test() {
|
||||||
|
std::thread t1 = support::make_test_thread(helper);
|
||||||
|
std::thread t2 = support::make_test_thread(helper);
|
||||||
|
t1.join();
|
||||||
|
t2.join();
|
||||||
|
assert(run_count == 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that we don't re-initialize a static variable even when it's
|
||||||
|
// encountered from two different threads.
|
||||||
|
namespace test5 {
|
||||||
|
static int run_count = 0;
|
||||||
|
int zero() {
|
||||||
|
++run_count;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int one() {
|
||||||
|
static int b = zero(); ((void)b);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void another_helper() {
|
||||||
|
static int a = one(); ((void)a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void helper() {
|
||||||
|
static int a = one(); ((void)a);
|
||||||
|
std::thread t = support::make_test_thread(another_helper);
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
void test() {
|
||||||
|
std::thread t = support::make_test_thread(helper);
|
||||||
|
t.join();
|
||||||
|
assert(run_count == 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* TEST_HAS_NO_THREADS */
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
test1::test();
|
||||||
|
test2::test();
|
||||||
|
test3::test();
|
||||||
|
#ifndef TEST_HAS_NO_THREADS
|
||||||
|
test4::test();
|
||||||
|
test5::test();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
278
third_party/libcxxabi/test/test_vector1.pass.cc
vendored
Normal file
278
third_party/libcxxabi/test/test_vector1.pass.cc
vendored
Normal file
|
@ -0,0 +1,278 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "third_party/libcxxabi/include/cxxabi.h"
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
#include "third_party/libcxx/cstdio"
|
||||||
|
#include "third_party/libcxx/cstdlib"
|
||||||
|
|
||||||
|
#include "third_party/libcxxabi/libcxx/test/support/test_macros.hh"
|
||||||
|
|
||||||
|
// Wrapper routines
|
||||||
|
void *my_alloc2 ( size_t sz ) {
|
||||||
|
void *p = std::malloc ( sz );
|
||||||
|
// std::printf ( "Allocated %ld bytes at %lx\n", sz, (unsigned long) p );
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void my_dealloc2 ( void *p ) {
|
||||||
|
// std::printf ( "Freeing %lx\n", (unsigned long) p );
|
||||||
|
std::free ( p );
|
||||||
|
}
|
||||||
|
|
||||||
|
void my_dealloc3 ( void *p, size_t ) {
|
||||||
|
// std::printf ( "Freeing %lx (size %ld)\n", (unsigned long) p, sz );
|
||||||
|
std::free ( p );
|
||||||
|
}
|
||||||
|
|
||||||
|
void my_construct ( void * ) {
|
||||||
|
// std::printf ( "Constructing %lx\n", (unsigned long) p );
|
||||||
|
}
|
||||||
|
|
||||||
|
void my_destruct ( void * ) {
|
||||||
|
// std::printf ( "Destructing %lx\n", (unsigned long) p );
|
||||||
|
}
|
||||||
|
|
||||||
|
int gCounter;
|
||||||
|
void count_construct ( void * ) { ++gCounter; }
|
||||||
|
void count_destruct ( void * ) { --gCounter; }
|
||||||
|
|
||||||
|
|
||||||
|
int gConstructorCounter;
|
||||||
|
int gConstructorThrowTarget;
|
||||||
|
int gDestructorCounter;
|
||||||
|
int gDestructorThrowTarget;
|
||||||
|
void throw_construct ( void * ) {
|
||||||
|
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||||
|
if ( gConstructorCounter == gConstructorThrowTarget )
|
||||||
|
throw 1;
|
||||||
|
++gConstructorCounter;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void throw_destruct ( void * ) {
|
||||||
|
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||||
|
if ( ++gDestructorCounter == gDestructorThrowTarget )
|
||||||
|
throw 2;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
# define CAN_THROW noexcept(false)
|
||||||
|
#else
|
||||||
|
# define CAN_THROW
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct vec_on_stack {
|
||||||
|
void *storage;
|
||||||
|
vec_on_stack () : storage ( __cxxabiv1::__cxa_vec_new ( 10, 40, 8, throw_construct, throw_destruct )) {}
|
||||||
|
~vec_on_stack () CAN_THROW {__cxxabiv1::__cxa_vec_delete ( storage, 40, 8, throw_destruct ); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test calls with empty constructors and destructors
|
||||||
|
int test_empty ( ) {
|
||||||
|
void *one, *two, *three;
|
||||||
|
|
||||||
|
// Try with no padding and no con/destructors
|
||||||
|
one = __cxxabiv1::__cxa_vec_new ( 10, 40, 0, NULL, NULL );
|
||||||
|
two = __cxxabiv1::__cxa_vec_new2( 10, 40, 0, NULL, NULL, my_alloc2, my_dealloc2 );
|
||||||
|
three = __cxxabiv1::__cxa_vec_new3( 10, 40, 0, NULL, NULL, my_alloc2, my_dealloc3 );
|
||||||
|
|
||||||
|
__cxxabiv1::__cxa_vec_delete ( one, 40, 0, NULL );
|
||||||
|
__cxxabiv1::__cxa_vec_delete2( two, 40, 0, NULL, my_dealloc2 );
|
||||||
|
__cxxabiv1::__cxa_vec_delete3( three, 40, 0, NULL, my_dealloc3 );
|
||||||
|
|
||||||
|
// Try with no padding
|
||||||
|
one = __cxxabiv1::__cxa_vec_new ( 10, 40, 0, my_construct, my_destruct );
|
||||||
|
two = __cxxabiv1::__cxa_vec_new2( 10, 40, 0, my_construct, my_destruct, my_alloc2, my_dealloc2 );
|
||||||
|
three = __cxxabiv1::__cxa_vec_new3( 10, 40, 0, my_construct, my_destruct, my_alloc2, my_dealloc3 );
|
||||||
|
|
||||||
|
__cxxabiv1::__cxa_vec_delete ( one, 40, 0, my_destruct );
|
||||||
|
__cxxabiv1::__cxa_vec_delete2( two, 40, 0, my_destruct, my_dealloc2 );
|
||||||
|
__cxxabiv1::__cxa_vec_delete3( three, 40, 0, my_destruct, my_dealloc3 );
|
||||||
|
|
||||||
|
// Padding and no con/destructors
|
||||||
|
one = __cxxabiv1::__cxa_vec_new ( 10, 40, 8, NULL, NULL );
|
||||||
|
two = __cxxabiv1::__cxa_vec_new2( 10, 40, 8, NULL, NULL, my_alloc2, my_dealloc2 );
|
||||||
|
three = __cxxabiv1::__cxa_vec_new3( 10, 40, 8, NULL, NULL, my_alloc2, my_dealloc3 );
|
||||||
|
|
||||||
|
__cxxabiv1::__cxa_vec_delete ( one, 40, 8, NULL );
|
||||||
|
__cxxabiv1::__cxa_vec_delete2( two, 40, 8, NULL, my_dealloc2 );
|
||||||
|
__cxxabiv1::__cxa_vec_delete3( three, 40, 8, NULL, my_dealloc3 );
|
||||||
|
|
||||||
|
// Padding with con/destructors
|
||||||
|
one = __cxxabiv1::__cxa_vec_new ( 10, 40, 8, my_construct, my_destruct );
|
||||||
|
two = __cxxabiv1::__cxa_vec_new2( 10, 40, 8, my_construct, my_destruct, my_alloc2, my_dealloc2 );
|
||||||
|
three = __cxxabiv1::__cxa_vec_new3( 10, 40, 8, my_construct, my_destruct, my_alloc2, my_dealloc3 );
|
||||||
|
|
||||||
|
__cxxabiv1::__cxa_vec_delete ( one, 40, 8, my_destruct );
|
||||||
|
__cxxabiv1::__cxa_vec_delete2( two, 40, 8, my_destruct, my_dealloc2 );
|
||||||
|
__cxxabiv1::__cxa_vec_delete3( three, 40, 8, my_destruct, my_dealloc3 );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the constructors and destructors are matched
|
||||||
|
int test_counted ( ) {
|
||||||
|
int retVal = 0;
|
||||||
|
void *one, *two, *three;
|
||||||
|
|
||||||
|
// Try with no padding
|
||||||
|
gCounter = 0;
|
||||||
|
one = __cxxabiv1::__cxa_vec_new ( 10, 40, 0, count_construct, count_destruct );
|
||||||
|
two = __cxxabiv1::__cxa_vec_new2( 10, 40, 0, count_construct, count_destruct, my_alloc2, my_dealloc2 );
|
||||||
|
three = __cxxabiv1::__cxa_vec_new3( 10, 40, 0, count_construct, count_destruct, my_alloc2, my_dealloc3 );
|
||||||
|
|
||||||
|
__cxxabiv1::__cxa_vec_delete ( one, 40, 0, count_destruct );
|
||||||
|
__cxxabiv1::__cxa_vec_delete2( two, 40, 0, count_destruct, my_dealloc2 );
|
||||||
|
__cxxabiv1::__cxa_vec_delete3( three, 40, 0, count_destruct, my_dealloc3 );
|
||||||
|
|
||||||
|
// Since there was no padding, the # of elements in the array are not stored
|
||||||
|
// and the destructors are not called.
|
||||||
|
if ( gCounter != 30 ) {
|
||||||
|
std::printf("Mismatched Constructor/Destructor calls (1)\n");
|
||||||
|
std::printf(" Expected 30, got %d\n", gCounter);
|
||||||
|
retVal = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
gCounter = 0;
|
||||||
|
one = __cxxabiv1::__cxa_vec_new ( 10, 40, 8, count_construct, count_destruct );
|
||||||
|
two = __cxxabiv1::__cxa_vec_new2( 10, 40, 8, count_construct, count_destruct, my_alloc2, my_dealloc2 );
|
||||||
|
three = __cxxabiv1::__cxa_vec_new3( 10, 40, 8, count_construct, count_destruct, my_alloc2, my_dealloc3 );
|
||||||
|
|
||||||
|
__cxxabiv1::__cxa_vec_delete ( one, 40, 8, count_destruct );
|
||||||
|
__cxxabiv1::__cxa_vec_delete2( two, 40, 8, count_destruct, my_dealloc2 );
|
||||||
|
__cxxabiv1::__cxa_vec_delete3( three, 40, 8, count_destruct, my_dealloc3 );
|
||||||
|
|
||||||
|
if ( gCounter != 0 ) {
|
||||||
|
std::printf("Mismatched Constructor/Destructor calls (2)\n");
|
||||||
|
std::printf(" Expected 0, got %d\n", gCounter);
|
||||||
|
retVal = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||||
|
// Make sure the constructors and destructors are matched
|
||||||
|
int test_exception_in_constructor ( ) {
|
||||||
|
int retVal = 0;
|
||||||
|
void *one, *two, *three;
|
||||||
|
|
||||||
|
// Try with no padding
|
||||||
|
gConstructorCounter = gDestructorCounter = 0;
|
||||||
|
gConstructorThrowTarget = 15;
|
||||||
|
gDestructorThrowTarget = -1;
|
||||||
|
try {
|
||||||
|
one = two = three = NULL;
|
||||||
|
one = __cxxabiv1::__cxa_vec_new ( 10, 40, 0, throw_construct, throw_destruct );
|
||||||
|
two = __cxxabiv1::__cxa_vec_new2( 10, 40, 0, throw_construct, throw_destruct, my_alloc2, my_dealloc2 );
|
||||||
|
three = __cxxabiv1::__cxa_vec_new3( 10, 40, 0, throw_construct, throw_destruct, my_alloc2, my_dealloc3 );
|
||||||
|
}
|
||||||
|
catch ( int i ) {}
|
||||||
|
|
||||||
|
__cxxabiv1::__cxa_vec_delete ( one, 40, 0, throw_destruct );
|
||||||
|
__cxxabiv1::__cxa_vec_delete2( two, 40, 0, throw_destruct, my_dealloc2 );
|
||||||
|
__cxxabiv1::__cxa_vec_delete3( three, 40, 0, throw_destruct, my_dealloc3 );
|
||||||
|
|
||||||
|
// Since there was no padding, the # of elements in the array are not stored
|
||||||
|
// and the destructors are not called.
|
||||||
|
// Since we threw after 15 calls to the constructor, we should see 5 calls to
|
||||||
|
// the destructor from the partially constructed array.
|
||||||
|
if ( gConstructorCounter - gDestructorCounter != 10 ) {
|
||||||
|
std::printf("Mismatched Constructor/Destructor calls (1C)\n");
|
||||||
|
std::printf("%d constructors, but %d destructors\n", gConstructorCounter, gDestructorCounter);
|
||||||
|
retVal = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
gConstructorCounter = gDestructorCounter = 0;
|
||||||
|
gConstructorThrowTarget = 15;
|
||||||
|
gDestructorThrowTarget = -1;
|
||||||
|
try {
|
||||||
|
one = two = three = NULL;
|
||||||
|
one = __cxxabiv1::__cxa_vec_new ( 10, 40, 8, throw_construct, throw_destruct );
|
||||||
|
two = __cxxabiv1::__cxa_vec_new2( 10, 40, 8, throw_construct, throw_destruct, my_alloc2, my_dealloc2 );
|
||||||
|
three = __cxxabiv1::__cxa_vec_new3( 10, 40, 8, throw_construct, throw_destruct, my_alloc2, my_dealloc3 );
|
||||||
|
}
|
||||||
|
catch ( int i ) {}
|
||||||
|
|
||||||
|
__cxxabiv1::__cxa_vec_delete ( one, 40, 8, throw_destruct );
|
||||||
|
__cxxabiv1::__cxa_vec_delete2( two, 40, 8, throw_destruct, my_dealloc2 );
|
||||||
|
__cxxabiv1::__cxa_vec_delete3( three, 40, 8, throw_destruct, my_dealloc3 );
|
||||||
|
|
||||||
|
if ( gConstructorCounter != gDestructorCounter ) {
|
||||||
|
std::printf("Mismatched Constructor/Destructor calls (2C)\n");
|
||||||
|
std::printf("%d constructors, but %d destructors\n", gConstructorCounter, gDestructorCounter);
|
||||||
|
retVal = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||||
|
// Make sure the constructors and destructors are matched
|
||||||
|
int test_exception_in_destructor ( ) {
|
||||||
|
int retVal = 0;
|
||||||
|
void *one, *two, *three;
|
||||||
|
one = two = three = NULL;
|
||||||
|
|
||||||
|
// Throw from within a destructor
|
||||||
|
gConstructorCounter = gDestructorCounter = 0;
|
||||||
|
gConstructorThrowTarget = -1;
|
||||||
|
gDestructorThrowTarget = 15;
|
||||||
|
try {
|
||||||
|
one = two = NULL;
|
||||||
|
one = __cxxabiv1::__cxa_vec_new ( 10, 40, 8, throw_construct, throw_destruct );
|
||||||
|
two = __cxxabiv1::__cxa_vec_new2( 10, 40, 8, throw_construct, throw_destruct, my_alloc2, my_dealloc2 );
|
||||||
|
}
|
||||||
|
catch ( int i ) {}
|
||||||
|
|
||||||
|
try {
|
||||||
|
__cxxabiv1::__cxa_vec_delete ( one, 40, 8, throw_destruct );
|
||||||
|
__cxxabiv1::__cxa_vec_delete2( two, 40, 8, throw_destruct, my_dealloc2 );
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch ( int i ) {}
|
||||||
|
|
||||||
|
// We should have thrown in the middle of cleaning up "two", which means that
|
||||||
|
// there should be 20 calls to the destructor and the try block should exit
|
||||||
|
// before the assertion.
|
||||||
|
if ( gConstructorCounter != 20 || gDestructorCounter != 20 ) {
|
||||||
|
std::printf("Unexpected Constructor/Destructor calls (1D)\n");
|
||||||
|
std::printf("Expected (20, 20), but got (%d, %d)\n", gConstructorCounter, gDestructorCounter);
|
||||||
|
retVal = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try throwing from a destructor - should be fine.
|
||||||
|
gConstructorCounter = gDestructorCounter = 0;
|
||||||
|
gConstructorThrowTarget = -1;
|
||||||
|
gDestructorThrowTarget = 5;
|
||||||
|
try { vec_on_stack v; }
|
||||||
|
catch ( int i ) {}
|
||||||
|
|
||||||
|
if ( gConstructorCounter != gDestructorCounter ) {
|
||||||
|
std::printf("Mismatched Constructor/Destructor calls (2D)\n");
|
||||||
|
std::printf("%d constructors, but %d destructors\n", gConstructorCounter, gDestructorCounter);
|
||||||
|
retVal = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
int retVal = 0;
|
||||||
|
retVal += test_empty ();
|
||||||
|
retVal += test_counted ();
|
||||||
|
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||||
|
retVal += test_exception_in_constructor ();
|
||||||
|
retVal += test_exception_in_destructor ();
|
||||||
|
#endif
|
||||||
|
return retVal;
|
||||||
|
}
|
86
third_party/libcxxabi/test/test_vector2.pass.cc
vendored
Normal file
86
third_party/libcxxabi/test/test_vector2.pass.cc
vendored
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
#include "third_party/libcxxabi/include/cxxabi.h"
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
#include "third_party/libcxx/cstdlib"
|
||||||
|
#include "third_party/libcxx/exception"
|
||||||
|
|
||||||
|
void my_terminate () { exit ( 0 ); }
|
||||||
|
|
||||||
|
// Wrapper routines
|
||||||
|
void *my_alloc2 ( size_t sz ) {
|
||||||
|
void *p = std::malloc ( sz );
|
||||||
|
// std::printf ( "Allocated %ld bytes at %lx\n", sz, (unsigned long) p );
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void my_dealloc2 ( void *p ) {
|
||||||
|
// std::printf ( "Freeing %lx\n", (unsigned long) p );
|
||||||
|
std::free ( p );
|
||||||
|
}
|
||||||
|
|
||||||
|
void my_dealloc3 ( void *p, size_t ) {
|
||||||
|
// std::printf ( "Freeing %lx (size %ld)\n", (unsigned long) p, sz );
|
||||||
|
std::free ( p );
|
||||||
|
}
|
||||||
|
|
||||||
|
void my_construct ( void *) {
|
||||||
|
// std::printf ( "Constructing %lx\n", (unsigned long) p );
|
||||||
|
}
|
||||||
|
|
||||||
|
void my_destruct ( void *) {
|
||||||
|
// std::printf ( "Destructing %lx\n", (unsigned long) p );
|
||||||
|
}
|
||||||
|
|
||||||
|
int gCounter;
|
||||||
|
void count_construct ( void * ) { ++gCounter; }
|
||||||
|
void count_destruct ( void * ) { --gCounter; }
|
||||||
|
|
||||||
|
|
||||||
|
int gConstructorCounter;
|
||||||
|
int gConstructorThrowTarget;
|
||||||
|
int gDestructorCounter;
|
||||||
|
int gDestructorThrowTarget;
|
||||||
|
void throw_construct ( void * ) { if ( gConstructorCounter == gConstructorThrowTarget ) throw 1; ++gConstructorCounter; }
|
||||||
|
void throw_destruct ( void * ) { if ( ++gDestructorCounter == gDestructorThrowTarget ) throw 2; }
|
||||||
|
|
||||||
|
struct vec_on_stack {
|
||||||
|
void *storage;
|
||||||
|
vec_on_stack () : storage ( __cxxabiv1::__cxa_vec_new ( 10, 40, 8, throw_construct, throw_destruct )) {}
|
||||||
|
~vec_on_stack () { __cxxabiv1::__cxa_vec_delete ( storage, 40, 8, throw_destruct ); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Make sure the constructors and destructors are matched
|
||||||
|
void test_exception_in_destructor ( ) {
|
||||||
|
|
||||||
|
// Try throwing from a destructor while unwinding the stack -- should abort
|
||||||
|
gConstructorCounter = gDestructorCounter = 0;
|
||||||
|
gConstructorThrowTarget = -1;
|
||||||
|
gDestructorThrowTarget = 5;
|
||||||
|
try {
|
||||||
|
vec_on_stack v;
|
||||||
|
throw 3;
|
||||||
|
} catch ( int i ) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false && "should never get here");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main () {
|
||||||
|
std::set_terminate ( my_terminate );
|
||||||
|
test_exception_in_destructor ();
|
||||||
|
return 1; // we failed if we get here
|
||||||
|
}
|
66
third_party/libcxxabi/test/test_vector3.pass.cc
vendored
Normal file
66
third_party/libcxxabi/test/test_vector3.pass.cc
vendored
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
#include "third_party/libcxxabi/include/cxxabi.h"
|
||||||
|
|
||||||
|
#include "libc/isystem/stdio.h"
|
||||||
|
#include "libc/isystem/stdlib.h"
|
||||||
|
#include "libc/isystem/assert.h"
|
||||||
|
#include "third_party/libcxx/exception"
|
||||||
|
|
||||||
|
#include "third_party/libcxx/memory"
|
||||||
|
|
||||||
|
// Disable warning about throw always calling terminate.
|
||||||
|
#if defined(__GNUC__) && !defined(__clang__)
|
||||||
|
# pragma GCC diagnostic ignored "-Wterminate"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// use dtors instead of try/catch
|
||||||
|
namespace test1 {
|
||||||
|
struct B {
|
||||||
|
~B() {
|
||||||
|
printf("should not be run\n");
|
||||||
|
exit(10);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct A {
|
||||||
|
~A()
|
||||||
|
#if __has_feature(cxx_noexcept)
|
||||||
|
noexcept(false)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
B b;
|
||||||
|
throw 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // test1
|
||||||
|
|
||||||
|
void my_terminate() { exit(0); }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void destroy(void* v)
|
||||||
|
{
|
||||||
|
T* t = static_cast<T*>(v);
|
||||||
|
t->~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
std::set_terminate(my_terminate);
|
||||||
|
{
|
||||||
|
typedef test1::A Array[10];
|
||||||
|
Array a[10]; // calls _cxa_vec_dtor
|
||||||
|
__cxxabiv1::__cxa_vec_dtor(a, 10, sizeof(test1::A), destroy<test1::A>);
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
67
third_party/libcxxabi/test/thread_local_destruction_order.pass.cc
vendored
Normal file
67
third_party/libcxxabi/test/thread_local_destruction_order.pass.cc
vendored
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++03
|
||||||
|
// UNSUPPORTED: no-threads
|
||||||
|
|
||||||
|
// XFAIL: LIBCXX-FREEBSD-FIXME
|
||||||
|
|
||||||
|
// TODO: This test does start working with newer updates of the mingw-w64
|
||||||
|
// toolchain, when it includes the following commit:
|
||||||
|
// https://github.com/mingw-w64/mingw-w64/commit/71eddccd746c56d9cde28bb5620d027d49259de9
|
||||||
|
// Thus, remove this UNSUPPORTED marking after the next update of the CI
|
||||||
|
// toolchain.
|
||||||
|
// UNSUPPORTED: target={{.*-windows-gnu}}
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
#include "third_party/libcxx/thread"
|
||||||
|
|
||||||
|
#include "third_party/libcxxabi/libcxx/test/support/make_test_thread.hh"
|
||||||
|
|
||||||
|
int seq = 0;
|
||||||
|
|
||||||
|
class OrderChecker {
|
||||||
|
public:
|
||||||
|
explicit OrderChecker(int n) : n_{n} { }
|
||||||
|
|
||||||
|
~OrderChecker() {
|
||||||
|
assert(seq++ == n_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int n_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <int ID>
|
||||||
|
class CreatesThreadLocalInDestructor {
|
||||||
|
public:
|
||||||
|
~CreatesThreadLocalInDestructor() {
|
||||||
|
thread_local OrderChecker checker{ID};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
OrderChecker global{7};
|
||||||
|
|
||||||
|
void thread_fn() {
|
||||||
|
static OrderChecker fn_static{5};
|
||||||
|
thread_local CreatesThreadLocalInDestructor<2> creates_tl2;
|
||||||
|
thread_local OrderChecker fn_thread_local{1};
|
||||||
|
thread_local CreatesThreadLocalInDestructor<0> creates_tl0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
static OrderChecker fn_static{6};
|
||||||
|
|
||||||
|
support::make_test_thread(thread_fn).join();
|
||||||
|
assert(seq == 3);
|
||||||
|
|
||||||
|
thread_local OrderChecker fn_thread_local{4};
|
||||||
|
thread_local CreatesThreadLocalInDestructor<3> creates_tl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
28
third_party/libcxxabi/test/uncaught_exception.pass.cc
vendored
Normal file
28
third_party/libcxxabi/test/uncaught_exception.pass.cc
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
// This tests that libc++abi still provides __cxa_uncaught_exception() for
|
||||||
|
// ABI compatibility, even though the Standard doesn't require it to.
|
||||||
|
|
||||||
|
#include "third_party/libcxxabi/include/cxxabi.h"
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
|
||||||
|
// namespace __cxxabiv1 {
|
||||||
|
// extern bool __cxa_uncaught_exception () throw();
|
||||||
|
// }
|
||||||
|
|
||||||
|
struct A {
|
||||||
|
~A() { assert( __cxxabiv1::__cxa_uncaught_exception()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
int main () {
|
||||||
|
try { A a; throw 3; assert(false); }
|
||||||
|
catch (int) {}
|
||||||
|
}
|
30
third_party/libcxxabi/test/uncaught_exceptions.pass.cc
vendored
Normal file
30
third_party/libcxxabi/test/uncaught_exceptions.pass.cc
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
// __cxa_uncaught_exceptions is not re-exported from libc++ until macOS 10.15.
|
||||||
|
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14}}
|
||||||
|
|
||||||
|
#include "third_party/libcxxabi/include/cxxabi.h"
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
|
||||||
|
// namespace __cxxabiv1 {
|
||||||
|
// extern unsigned int __cxa_uncaught_exceptions() throw();
|
||||||
|
// }
|
||||||
|
|
||||||
|
struct A {
|
||||||
|
A(unsigned cnt) : data_(cnt) {}
|
||||||
|
~A() { assert( data_ == __cxxabiv1::__cxa_uncaught_exceptions()); }
|
||||||
|
unsigned data_;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main () {
|
||||||
|
try { A a(1); throw 3; assert(false); }
|
||||||
|
catch (int) {}
|
||||||
|
}
|
89
third_party/libcxxabi/test/unittest_demangle.pass.cc
vendored
Normal file
89
third_party/libcxxabi/test/unittest_demangle.pass.cc
vendored
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++03
|
||||||
|
// ADDITIONAL_COMPILE_FLAGS: -Wno-unused-function
|
||||||
|
|
||||||
|
#include "third_party/libcxx/cassert"
|
||||||
|
#include "third_party/libcxx/utility"
|
||||||
|
|
||||||
|
#include "third_party/libcxxabi/demangle/ItaniumDemangle.h"
|
||||||
|
|
||||||
|
void testPODSmallVector() {
|
||||||
|
{ // {push/pop}_back
|
||||||
|
itanium_demangle::PODSmallVector<int, 1> PSV;
|
||||||
|
PSV.push_back(0);
|
||||||
|
PSV.push_back(1);
|
||||||
|
PSV.push_back(2);
|
||||||
|
PSV.push_back(3);
|
||||||
|
for (int i = 0; i < 4; ++i)
|
||||||
|
assert(PSV[i] == i);
|
||||||
|
PSV.pop_back();
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
assert(PSV[i] == i);
|
||||||
|
PSV.pop_back();
|
||||||
|
PSV.pop_back();
|
||||||
|
assert(!PSV.empty() && PSV.size() == 1);
|
||||||
|
PSV.pop_back();
|
||||||
|
assert(PSV.empty() && PSV.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
itanium_demangle::PODSmallVector<int, 1> PSV1;
|
||||||
|
PSV1.push_back(1);
|
||||||
|
PSV1.push_back(2);
|
||||||
|
PSV1.push_back(3);
|
||||||
|
|
||||||
|
itanium_demangle::PODSmallVector<int, 1> PSV2;
|
||||||
|
std::swap(PSV1, PSV2);
|
||||||
|
assert(PSV1.size() == 0);
|
||||||
|
assert(PSV2.size() == 3);
|
||||||
|
int i = 1;
|
||||||
|
for (int x : PSV2) {
|
||||||
|
assert(x == i);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
assert(i == 4);
|
||||||
|
std::swap(PSV1, PSV2);
|
||||||
|
assert(PSV1.size() == 3);
|
||||||
|
assert(PSV2.size() == 0);
|
||||||
|
i = 1;
|
||||||
|
for (int x : PSV1) {
|
||||||
|
assert(x == i);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
assert(i == 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
itanium_demangle::PODSmallVector<int, 10> PSV1;
|
||||||
|
itanium_demangle::PODSmallVector<int, 10> PSV2;
|
||||||
|
PSV1.push_back(0);
|
||||||
|
PSV1.push_back(1);
|
||||||
|
PSV1.push_back(2);
|
||||||
|
assert(PSV1.size() == 3);
|
||||||
|
assert(PSV2.size() == 0);
|
||||||
|
std::swap(PSV1, PSV2);
|
||||||
|
assert(PSV1.size() == 0);
|
||||||
|
assert(PSV2.size() == 3);
|
||||||
|
int i = 0;
|
||||||
|
for (int x : PSV2) {
|
||||||
|
assert(x == i);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
for (int x : PSV1) {
|
||||||
|
assert(false);
|
||||||
|
(void)x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
testPODSmallVector();
|
||||||
|
return 0;
|
||||||
|
}
|
103
third_party/libcxxabi/test/unwind_01.pass.cc
vendored
Normal file
103
third_party/libcxxabi/test/unwind_01.pass.cc
vendored
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
#include "libc/isystem/assert.h"
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic ignored "-Wunreachable-code"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct A
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
A() : id_(++count) {}
|
||||||
|
~A() {assert(id_ == count--);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
A(const A&);
|
||||||
|
A& operator=(const A&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int A::count = 0;
|
||||||
|
|
||||||
|
struct B
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
B() : id_(++count) {}
|
||||||
|
~B() {assert(id_ == count--);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
B(const B&);
|
||||||
|
B& operator=(const B&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int B::count = 0;
|
||||||
|
|
||||||
|
struct C
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
C() : id_(++count) {}
|
||||||
|
~C() {assert(id_ == count--);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
C(const C&);
|
||||||
|
C& operator=(const C&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int C::count = 0;
|
||||||
|
|
||||||
|
void f2()
|
||||||
|
{
|
||||||
|
C c;
|
||||||
|
A a;
|
||||||
|
throw 55;
|
||||||
|
B b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void f1()
|
||||||
|
{
|
||||||
|
A a;
|
||||||
|
B b;
|
||||||
|
f2();
|
||||||
|
C c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f1();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (int* i)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (long i)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (int i)
|
||||||
|
{
|
||||||
|
assert(i == 55);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
assert(C::count == 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
105
third_party/libcxxabi/test/unwind_02.pass.cc
vendored
Normal file
105
third_party/libcxxabi/test/unwind_02.pass.cc
vendored
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
// REQUIRES: c++03 || c++11 || c++14
|
||||||
|
|
||||||
|
#include "libc/isystem/assert.h"
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic ignored "-Wunreachable-code"
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct A
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
A() : id_(++count) {}
|
||||||
|
~A() {assert(id_ == count--);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
A(const A&);
|
||||||
|
A& operator=(const A&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int A::count = 0;
|
||||||
|
|
||||||
|
struct B
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
B() : id_(++count) {}
|
||||||
|
~B() {assert(id_ == count--);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
B(const B&);
|
||||||
|
B& operator=(const B&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int B::count = 0;
|
||||||
|
|
||||||
|
struct C
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
C() : id_(++count) {}
|
||||||
|
~C() {assert(id_ == count--);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
C(const C&);
|
||||||
|
C& operator=(const C&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int C::count = 0;
|
||||||
|
|
||||||
|
void f2()
|
||||||
|
{
|
||||||
|
C c;
|
||||||
|
A a;
|
||||||
|
throw 55;
|
||||||
|
B b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void f1() throw (long, char, int, double)
|
||||||
|
{
|
||||||
|
A a;
|
||||||
|
B b;
|
||||||
|
f2();
|
||||||
|
C c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f1();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (int* i)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (long i)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (int i)
|
||||||
|
{
|
||||||
|
assert(i == 55);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
assert(C::count == 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
111
third_party/libcxxabi/test/unwind_03.pass.cc
vendored
Normal file
111
third_party/libcxxabi/test/unwind_03.pass.cc
vendored
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
// REQUIRES: c++03 || c++11 || c++14
|
||||||
|
|
||||||
|
#include "third_party/libcxx/exception"
|
||||||
|
#include "libc/isystem/stdlib.h"
|
||||||
|
#include "libc/isystem/assert.h"
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic ignored "-Wunreachable-code"
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct A
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
A() : id_(++count) {}
|
||||||
|
~A() {assert(id_ == count--);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
A(const A&);
|
||||||
|
A& operator=(const A&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int A::count = 0;
|
||||||
|
|
||||||
|
struct B
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
B() : id_(++count) {}
|
||||||
|
~B() {assert(id_ == count--);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
B(const B&);
|
||||||
|
B& operator=(const B&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int B::count = 0;
|
||||||
|
|
||||||
|
struct C
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
C() : id_(++count) {}
|
||||||
|
~C() {assert(id_ == count--);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
C(const C&);
|
||||||
|
C& operator=(const C&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int C::count = 0;
|
||||||
|
|
||||||
|
void f2()
|
||||||
|
{
|
||||||
|
C c;
|
||||||
|
A a;
|
||||||
|
throw 55;
|
||||||
|
B b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void f1() throw (long, char, double)
|
||||||
|
{
|
||||||
|
A a;
|
||||||
|
B b;
|
||||||
|
f2();
|
||||||
|
C c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void u_handler()
|
||||||
|
{
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
std::set_unexpected(u_handler);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f1();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (int* i)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (long i)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (int i)
|
||||||
|
{
|
||||||
|
assert(i == 55);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
117
third_party/libcxxabi/test/unwind_04.pass.cc
vendored
Normal file
117
third_party/libcxxabi/test/unwind_04.pass.cc
vendored
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
// REQUIRES: c++03 || c++11 || c++14
|
||||||
|
|
||||||
|
#include "third_party/libcxx/exception"
|
||||||
|
#include "libc/isystem/stdlib.h"
|
||||||
|
#include "libc/isystem/assert.h"
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic ignored "-Wunreachable-code"
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct A
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
A() : id_(++count) {}
|
||||||
|
~A() {assert(id_ == count--);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
A(const A&);
|
||||||
|
A& operator=(const A&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int A::count = 0;
|
||||||
|
|
||||||
|
struct B
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
B() : id_(++count) {}
|
||||||
|
~B() {assert(id_ == count--);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
B(const B&);
|
||||||
|
B& operator=(const B&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int B::count = 0;
|
||||||
|
|
||||||
|
struct C
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
C() : id_(++count) {}
|
||||||
|
~C() {assert(id_ == count--);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
C(const C&);
|
||||||
|
C& operator=(const C&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int C::count = 0;
|
||||||
|
|
||||||
|
void f2()
|
||||||
|
{
|
||||||
|
C c;
|
||||||
|
A a;
|
||||||
|
throw 55;
|
||||||
|
B b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void f1() throw (long, char, double)
|
||||||
|
{
|
||||||
|
A a;
|
||||||
|
B b;
|
||||||
|
f2();
|
||||||
|
C c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void u_handler()
|
||||||
|
{
|
||||||
|
throw 'a';
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
std::set_unexpected(u_handler);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f1();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (int* i)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (long i)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (int i)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (char c)
|
||||||
|
{
|
||||||
|
assert(c == 'a');
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
assert(C::count == 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
121
third_party/libcxxabi/test/unwind_05.pass.cc
vendored
Normal file
121
third_party/libcxxabi/test/unwind_05.pass.cc
vendored
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
// REQUIRES: c++03 || c++11 || c++14
|
||||||
|
|
||||||
|
#include "third_party/libcxx/exception"
|
||||||
|
#include "libc/isystem/stdlib.h"
|
||||||
|
#include "libc/isystem/assert.h"
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic ignored "-Wunreachable-code"
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct A
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
A() : id_(++count) {}
|
||||||
|
~A() {assert(id_ == count--);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
A(const A&);
|
||||||
|
A& operator=(const A&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int A::count = 0;
|
||||||
|
|
||||||
|
struct B
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
B() : id_(++count) {}
|
||||||
|
~B() {assert(id_ == count--);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
B(const B&);
|
||||||
|
B& operator=(const B&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int B::count = 0;
|
||||||
|
|
||||||
|
struct C
|
||||||
|
{
|
||||||
|
static int count;
|
||||||
|
int id_;
|
||||||
|
C() : id_(++count) {}
|
||||||
|
~C() {assert(id_ == count--);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
C(const C&);
|
||||||
|
C& operator=(const C&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int C::count = 0;
|
||||||
|
|
||||||
|
void f2()
|
||||||
|
{
|
||||||
|
C c;
|
||||||
|
A a;
|
||||||
|
throw 55;
|
||||||
|
B b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void f1() throw (long, char, double, std::bad_exception)
|
||||||
|
{
|
||||||
|
A a;
|
||||||
|
B b;
|
||||||
|
f2();
|
||||||
|
C c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void u_handler()
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
std::set_unexpected(u_handler);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f1();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (int* i)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (long i)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (int i)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (char c)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
catch (const std::bad_exception& e)
|
||||||
|
{
|
||||||
|
assert(true);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
assert(A::count == 0);
|
||||||
|
assert(B::count == 0);
|
||||||
|
assert(C::count == 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
263
third_party/libcxxabi/test/unwind_06.pass.cc
vendored
Normal file
263
third_party/libcxxabi/test/unwind_06.pass.cc
vendored
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: no-exceptions
|
||||||
|
|
||||||
|
#include "third_party/libcxx/exception"
|
||||||
|
#include "libc/isystem/stdlib.h"
|
||||||
|
#include "libc/isystem/assert.h"
|
||||||
|
#include "libc/stdio/stdio.h"
|
||||||
|
|
||||||
|
// Suppress diagnostics about deprecated volatile operations
|
||||||
|
#if defined(__GNUC__) && !defined(__clang__)
|
||||||
|
# pragma GCC diagnostic ignored "-Wvolatile"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Compile with -Os to get compiler uses float registers to hold float variables
|
||||||
|
|
||||||
|
double get_(int x) { return (double)x; }
|
||||||
|
|
||||||
|
double (* volatile get)(int) = get_;
|
||||||
|
|
||||||
|
volatile int counter;
|
||||||
|
|
||||||
|
double try1(bool v) {
|
||||||
|
double a = get(0);
|
||||||
|
double b = get(1);
|
||||||
|
for (counter = 100; counter; counter = counter - 1)
|
||||||
|
a += get(1) + b;
|
||||||
|
if (v) throw 10;
|
||||||
|
return get(0)+a+b;
|
||||||
|
}
|
||||||
|
|
||||||
|
double try2(bool v) {
|
||||||
|
double a = get(0);
|
||||||
|
double b = get(1);
|
||||||
|
double c = get(2);
|
||||||
|
for (counter = 100; counter; counter = counter - 1)
|
||||||
|
a += get(1) + b + c;
|
||||||
|
if (v) throw 10;
|
||||||
|
return get(0)+a+b+c;
|
||||||
|
}
|
||||||
|
|
||||||
|
double try3(bool v) {
|
||||||
|
double a = get(0);
|
||||||
|
double b = get(1);
|
||||||
|
double c = get(2);
|
||||||
|
double d = get(3);
|
||||||
|
for (counter = 100; counter; counter = counter - 1)
|
||||||
|
a += get(1) + b + c + d;
|
||||||
|
if (v) throw 10;
|
||||||
|
return get(0)+a+b+c+d;
|
||||||
|
}
|
||||||
|
|
||||||
|
double try4(bool v) {
|
||||||
|
double a = get(0);
|
||||||
|
double b = get(0);
|
||||||
|
double c = get(0);
|
||||||
|
double d = get(0);
|
||||||
|
double e = get(0);
|
||||||
|
for (counter = 100; counter; counter = counter - 1)
|
||||||
|
a += get(1) + b+c+d+e;
|
||||||
|
if (v) throw 10;
|
||||||
|
return get(0)+a+b+c+d+e;
|
||||||
|
}
|
||||||
|
|
||||||
|
double try5(bool v) {
|
||||||
|
double a = get(0);
|
||||||
|
double b = get(0);
|
||||||
|
double c = get(0);
|
||||||
|
double d = get(0);
|
||||||
|
double e = get(0);
|
||||||
|
double f = get(0);
|
||||||
|
for (counter = 100; counter; counter = counter - 1)
|
||||||
|
a += get(1) + b+c+d+e+f;
|
||||||
|
if (v) throw 10;
|
||||||
|
return get(0)+a+b+c+d+e+f;
|
||||||
|
}
|
||||||
|
|
||||||
|
double try6(bool v) {
|
||||||
|
double a = get(0);
|
||||||
|
double b = get(0);
|
||||||
|
double c = get(0);
|
||||||
|
double d = get(0);
|
||||||
|
double e = get(0);
|
||||||
|
double f = get(0);
|
||||||
|
double g = get(0);
|
||||||
|
for (counter = 100; counter; counter = counter - 1)
|
||||||
|
a += get(1) + b+c+d+e+f+g;
|
||||||
|
if (v) throw 10;
|
||||||
|
return get(0)+a+b+c+d+e+f+g;
|
||||||
|
}
|
||||||
|
|
||||||
|
double try7(bool v) {
|
||||||
|
double a = get(0);
|
||||||
|
double b = get(0);
|
||||||
|
double c = get(0);
|
||||||
|
double d = get(0);
|
||||||
|
double e = get(0);
|
||||||
|
double f = get(0);
|
||||||
|
double g = get(0);
|
||||||
|
double h = get(0);
|
||||||
|
for (counter = 100; counter; counter = counter - 1)
|
||||||
|
a += get(1) + b+c+d+e+f+g+h;
|
||||||
|
if (v) throw 10;
|
||||||
|
return get(0)+a+b+c+d+e+f+g+h;
|
||||||
|
}
|
||||||
|
|
||||||
|
double try8(bool v) {
|
||||||
|
double a = get(0);
|
||||||
|
double b = get(0);
|
||||||
|
double c = get(0);
|
||||||
|
double d = get(0);
|
||||||
|
double e = get(0);
|
||||||
|
double f = get(0);
|
||||||
|
double g = get(0);
|
||||||
|
double h = get(0);
|
||||||
|
double i = get(0);
|
||||||
|
for (counter = 100; counter; counter = counter - 1)
|
||||||
|
a += get(1) + b+c+d+e+f+g+h+i;
|
||||||
|
if (v) throw 10;
|
||||||
|
return get(0)+a+b+c+d+e+f+g+h+i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
double foo()
|
||||||
|
{
|
||||||
|
double a = get(1);
|
||||||
|
double b = get(2);
|
||||||
|
double c = get(3);
|
||||||
|
double d = get(4);
|
||||||
|
double e = get(5);
|
||||||
|
double f = get(6);
|
||||||
|
double g = get(7);
|
||||||
|
double h = get(8);
|
||||||
|
try {
|
||||||
|
try1(true);
|
||||||
|
}
|
||||||
|
catch (int) {
|
||||||
|
}
|
||||||
|
assert(a == get(1));
|
||||||
|
assert(b == get(2));
|
||||||
|
assert(c == get(3));
|
||||||
|
assert(d == get(4));
|
||||||
|
assert(e == get(5));
|
||||||
|
assert(f == get(6));
|
||||||
|
assert(g == get(7));
|
||||||
|
assert(h == get(8));
|
||||||
|
|
||||||
|
try {
|
||||||
|
try2(true);
|
||||||
|
}
|
||||||
|
catch (int) {
|
||||||
|
}
|
||||||
|
assert(a == get(1));
|
||||||
|
assert(b == get(2));
|
||||||
|
assert(c == get(3));
|
||||||
|
assert(d == get(4));
|
||||||
|
assert(e == get(5));
|
||||||
|
assert(f == get(6));
|
||||||
|
assert(g == get(7));
|
||||||
|
assert(h == get(8));
|
||||||
|
|
||||||
|
try {
|
||||||
|
try3(true);
|
||||||
|
}
|
||||||
|
catch (int) {
|
||||||
|
}
|
||||||
|
assert(a == get(1));
|
||||||
|
assert(b == get(2));
|
||||||
|
assert(c == get(3));
|
||||||
|
assert(d == get(4));
|
||||||
|
assert(e == get(5));
|
||||||
|
assert(f == get(6));
|
||||||
|
assert(g == get(7));
|
||||||
|
assert(h == get(8));
|
||||||
|
|
||||||
|
try {
|
||||||
|
try4(true);
|
||||||
|
}
|
||||||
|
catch (int) {
|
||||||
|
}
|
||||||
|
assert(a == get(1));
|
||||||
|
assert(b == get(2));
|
||||||
|
assert(c == get(3));
|
||||||
|
assert(d == get(4));
|
||||||
|
assert(e == get(5));
|
||||||
|
assert(f == get(6));
|
||||||
|
assert(g == get(7));
|
||||||
|
assert(h == get(8));
|
||||||
|
|
||||||
|
try {
|
||||||
|
try5(true);
|
||||||
|
}
|
||||||
|
catch (int) {
|
||||||
|
}
|
||||||
|
assert(a == get(1));
|
||||||
|
assert(b == get(2));
|
||||||
|
assert(c == get(3));
|
||||||
|
assert(d == get(4));
|
||||||
|
assert(e == get(5));
|
||||||
|
assert(f == get(6));
|
||||||
|
assert(g == get(7));
|
||||||
|
assert(h == get(8));
|
||||||
|
|
||||||
|
try {
|
||||||
|
try6(true);
|
||||||
|
}
|
||||||
|
catch (int) {
|
||||||
|
}
|
||||||
|
assert(a == get(1));
|
||||||
|
assert(b == get(2));
|
||||||
|
assert(c == get(3));
|
||||||
|
assert(d == get(4));
|
||||||
|
assert(e == get(5));
|
||||||
|
assert(f == get(6));
|
||||||
|
assert(g == get(7));
|
||||||
|
assert(h == get(8));
|
||||||
|
|
||||||
|
try {
|
||||||
|
try7(true);
|
||||||
|
}
|
||||||
|
catch (int) {
|
||||||
|
}
|
||||||
|
assert(a == get(1));
|
||||||
|
assert(b == get(2));
|
||||||
|
assert(c == get(3));
|
||||||
|
assert(d == get(4));
|
||||||
|
assert(e == get(5));
|
||||||
|
assert(f == get(6));
|
||||||
|
assert(g == get(7));
|
||||||
|
assert(h == get(8));
|
||||||
|
|
||||||
|
try {
|
||||||
|
try8(true);
|
||||||
|
}
|
||||||
|
catch (int) {
|
||||||
|
}
|
||||||
|
assert(a == get(1));
|
||||||
|
assert(b == get(2));
|
||||||
|
assert(c == get(3));
|
||||||
|
assert(d == get(4));
|
||||||
|
assert(e == get(5));
|
||||||
|
assert(f == get(6));
|
||||||
|
assert(g == get(7));
|
||||||
|
assert(h == get(8));
|
||||||
|
|
||||||
|
return a+b+c+d+e+f+g+h;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
foo();
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in a new issue