mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-25 23:02:27 +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
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;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue