Index: libcxxabi/trunk/CMakeLists.txt =================================================================== --- libcxxabi/trunk/CMakeLists.txt +++ libcxxabi/trunk/CMakeLists.txt @@ -108,6 +108,7 @@ #=============================================================================== # Define options. +option(LIBCXXABI_ENABLE_EXCEPTIONS "Use exceptions." ON) option(LIBCXXABI_ENABLE_ASSERTIONS "Enable assertions independent of build mode." ON) option(LIBCXXABI_ENABLE_PEDANTIC "Compile with pedantic enabled." ON) option(LIBCXXABI_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF) @@ -242,13 +243,20 @@ endif() # Get feature flags. -# Exceptions -# Catches C++ exceptions only and tells the compiler to assume that extern C -# functions never throw a C++ exception. append_if(LIBCXXABI_CXX_FLAGS LIBCXXABI_HAS_FSTRICT_ALIASING_FLAG -fstrict-aliasing) -append_if(LIBCXXABI_CXX_FLAGS LIBCXXABI_HAS_EHSC_FLAG -EHsc) -append_if(LIBCXXABI_C_FLAGS LIBCXXABI_HAS_FUNWIND_TABLES -funwind-tables) +# Exceptions +if (LIBCXXABI_ENABLE_EXCEPTIONS) + # Catches C++ exceptions only and tells the compiler to assume that extern C + # functions never throw a C++ exception. + append_if(LIBCXXABI_CXX_FLAGS LIBCXXABI_HAS_EHSC_FLAG -EHsc) + append_if(LIBCXXABI_C_FLAGS LIBCXXABI_HAS_FUNWIND_TABLES -funwind-tables) +else() + add_definitions(-D_LIBCXXABI_NO_EXCEPTIONS) + append_if(LIBCXXABI_CXX_FLAGS LIBCXXABI_HAS_NO_EXCEPTIONS_FLAG -fno-exceptions) + append_if(LIBCXXABI_CXX_FLAGS LIBCXXABI_HAS_NO_EHS_FLAG -EHs-) + append_if(LIBCXXABI_CXX_FLAGS LIBCXXABI_HAS_NO_EHA_FLAG -EHa-) +endif() append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_FVISIBILITY_HIDDEN_FLAG -fvisibility=hidden) Index: libcxxabi/trunk/src/CMakeLists.txt =================================================================== --- libcxxabi/trunk/src/CMakeLists.txt +++ libcxxabi/trunk/src/CMakeLists.txt @@ -4,12 +4,10 @@ cxa_aux_runtime.cpp cxa_default_handlers.cpp cxa_demangle.cpp - cxa_exception.cpp cxa_exception_storage.cpp cxa_guard.cpp cxa_handlers.cpp cxa_new_delete.cpp - cxa_personality.cpp cxa_unexpected.cpp cxa_vector.cpp cxa_virtual.cpp @@ -19,6 +17,13 @@ typeinfo.cpp ) +if (LIBCXXABI_ENABLE_EXCEPTIONS) + list(APPEND LIBCXXABI_SOURCES cxa_exception.cpp) + list(APPEND LIBCXXABI_SOURCES cxa_personality.cpp) +else() + list(APPEND LIBCXXABI_SOURCES cxa_noexception.cpp) +endif() + if (UNIX AND NOT (APPLE OR CYGWIN)) list(APPEND LIBCXXABI_SOURCES cxa_thread_atexit.cpp) endif() Index: libcxxabi/trunk/src/cxa_aux_runtime.cpp =================================================================== --- libcxxabi/trunk/src/cxa_aux_runtime.cpp +++ libcxxabi/trunk/src/cxa_aux_runtime.cpp @@ -17,16 +17,28 @@ namespace __cxxabiv1 { extern "C" { _LIBCXXABI_FUNC_VIS LIBCXXABI_NORETURN void __cxa_bad_cast(void) { +#ifndef _LIBCXXABI_NO_EXCEPTIONS throw std::bad_cast(); +#else + std::terminate(); +#endif } _LIBCXXABI_FUNC_VIS LIBCXXABI_NORETURN void __cxa_bad_typeid(void) { +#ifndef _LIBCXXABI_NO_EXCEPTIONS throw std::bad_typeid(); +#else + std::terminate(); +#endif } _LIBCXXABI_FUNC_VIS LIBCXXABI_NORETURN void __cxa_throw_bad_array_new_length(void) { +#ifndef _LIBCXXABI_NO_EXCEPTIONS throw std::bad_array_new_length(); +#else + std::terminate(); +#endif } } // extern "C" } // abi Index: libcxxabi/trunk/src/cxa_handlers.cpp =================================================================== --- libcxxabi/trunk/src/cxa_handlers.cpp +++ libcxxabi/trunk/src/cxa_handlers.cpp @@ -61,21 +61,21 @@ void __terminate(terminate_handler func) _NOEXCEPT { -#if __has_feature(cxx_exceptions) +#ifndef _LIBCXXABI_NO_EXCEPTIONS try { -#endif // __has_feature(cxx_exceptions) +#endif // _LIBCXXABI_NO_EXCEPTIONS func(); // handler should not return abort_message("terminate_handler unexpectedly returned"); -#if __has_feature(cxx_exceptions) +#ifndef _LIBCXXABI_NO_EXCEPTIONS } catch (...) { // handler should not throw exception abort_message("terminate_handler unexpectedly threw an exception"); } -#endif // #if __has_feature(cxx_exceptions) +#endif // _LIBCXXABI_NO_EXCEPTIONS } __attribute__((noreturn)) Index: libcxxabi/trunk/src/cxa_new_delete.cpp =================================================================== --- libcxxabi/trunk/src/cxa_new_delete.cpp +++ libcxxabi/trunk/src/cxa_new_delete.cpp @@ -47,7 +47,11 @@ if (nh) nh(); else +#ifndef _LIBCXXABI_NO_EXCEPTIONS throw std::bad_alloc(); +#else + break; +#endif } return p; } @@ -74,13 +78,17 @@ #endif { void* p = 0; +#ifndef _LIBCXXABI_NO_EXCEPTIONS try { +#endif p = ::operator new(size); +#ifndef _LIBCXXABI_NO_EXCEPTIONS } catch (...) { } +#endif return p; } @@ -115,13 +123,17 @@ #endif { void* p = 0; +#ifndef _LIBCXXABI_NO_EXCEPTIONS try { +#endif p = ::operator new[](size); +#ifndef _LIBCXXABI_NO_EXCEPTIONS } catch (...) { } +#endif return p; } Index: libcxxabi/trunk/src/cxa_noexception.cpp =================================================================== --- libcxxabi/trunk/src/cxa_noexception.cpp +++ libcxxabi/trunk/src/cxa_noexception.cpp @@ -0,0 +1,60 @@ +//===------------------------- cxa_exception.cpp --------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +// +// This file implements the "Exception Handling APIs" +// http://mentorembedded.github.io/cxx-abi/abi-eh.html +// +//===----------------------------------------------------------------------===// + +// Support functions for the no-exceptions libc++ library + +#include "config.h" +#include "cxxabi.h" + +#include // for std::terminate +#include "cxa_exception.hpp" +#include "cxa_handlers.hpp" + +namespace __cxxabiv1 { + +#pragma GCC visibility push(default) + +extern "C" { + +void +__cxa_increment_exception_refcount(void *thrown_object) throw() { + if (thrown_object != nullptr) + std::terminate(); +} + +void +__cxa_decrement_exception_refcount(void *thrown_object) throw() { + if (thrown_object != nullptr) + std::terminate(); +} + + +void *__cxa_current_primary_exception() throw() { return nullptr; } + +void +__cxa_rethrow_primary_exception(void* thrown_object) { + if (thrown_object != nullptr) + std::terminate(); +} + +bool +__cxa_uncaught_exception() throw() { return false; } + +unsigned int +__cxa_uncaught_exceptions() throw() { return 0; } + +} // extern "C" + +#pragma GCC visibility pop + +} // abi Index: libcxxabi/trunk/test/CMakeLists.txt =================================================================== --- libcxxabi/trunk/test/CMakeLists.txt +++ libcxxabi/trunk/test/CMakeLists.txt @@ -14,6 +14,7 @@ pythonize_bool(LIBCXX_ENABLE_SHARED) pythonize_bool(LIBCXXABI_ENABLE_SHARED) pythonize_bool(LIBCXXABI_ENABLE_THREADS) +pythonize_bool(LIBCXXABI_ENABLE_EXCEPTIONS) pythonize_bool(LIBCXXABI_USE_LLVM_UNWINDER) pythonize_bool(LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL) set(LIBCXXABI_TARGET_INFO "libcxx.test.target_info.LocalTI" CACHE STRING Index: libcxxabi/trunk/test/backtrace_test.pass.cpp =================================================================== --- libcxxabi/trunk/test/backtrace_test.pass.cpp +++ libcxxabi/trunk/test/backtrace_test.pass.cpp @@ -6,6 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// + +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: libcxxabi/trunk/test/catch_array_01.pass.cpp =================================================================== --- libcxxabi/trunk/test/catch_array_01.pass.cpp +++ libcxxabi/trunk/test/catch_array_01.pass.cpp @@ -9,10 +9,10 @@ // 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: libcxxabi-no-exceptions #include Index: libcxxabi/trunk/test/catch_array_02.pass.cpp =================================================================== --- libcxxabi/trunk/test/catch_array_02.pass.cpp +++ libcxxabi/trunk/test/catch_array_02.pass.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// // Can you have a catch clause of array type that catches anything? +// UNSUPPORTED: libcxxabi-no-exceptions #include Index: libcxxabi/trunk/test/catch_class_01.pass.cpp =================================================================== --- libcxxabi/trunk/test/catch_class_01.pass.cpp +++ libcxxabi/trunk/test/catch_class_01.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: libcxxabi/trunk/test/catch_class_02.pass.cpp =================================================================== --- libcxxabi/trunk/test/catch_class_02.pass.cpp +++ libcxxabi/trunk/test/catch_class_02.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: libcxxabi/trunk/test/catch_class_03.pass.cpp =================================================================== --- libcxxabi/trunk/test/catch_class_03.pass.cpp +++ libcxxabi/trunk/test/catch_class_03.pass.cpp @@ -13,6 +13,8 @@ check against. */ +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: libcxxabi/trunk/test/catch_class_04.pass.cpp =================================================================== --- libcxxabi/trunk/test/catch_class_04.pass.cpp +++ libcxxabi/trunk/test/catch_class_04.pass.cpp @@ -13,6 +13,8 @@ check against. It also checks that virtual bases work properly */ +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: libcxxabi/trunk/test/catch_const_pointer_nullptr.pass.cpp =================================================================== --- libcxxabi/trunk/test/catch_const_pointer_nullptr.pass.cpp +++ libcxxabi/trunk/test/catch_const_pointer_nullptr.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #if __has_feature(cxx_nullptr) Index: libcxxabi/trunk/test/catch_function_01.pass.cpp =================================================================== --- libcxxabi/trunk/test/catch_function_01.pass.cpp +++ libcxxabi/trunk/test/catch_function_01.pass.cpp @@ -12,6 +12,7 @@ // GCC incorrectly allows function pointer to be caught by reference. // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69372 // XFAIL: gcc +// UNSUPPORTED: libcxxabi-no-exceptions #include Index: libcxxabi/trunk/test/catch_function_02.pass.cpp =================================================================== --- libcxxabi/trunk/test/catch_function_02.pass.cpp +++ libcxxabi/trunk/test/catch_function_02.pass.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// // Can you have a catch clause of array type that catches anything? +// UNSUPPORTED: libcxxabi-no-exceptions #include Index: libcxxabi/trunk/test/catch_in_noexcept.pass.cpp =================================================================== --- libcxxabi/trunk/test/catch_in_noexcept.pass.cpp +++ libcxxabi/trunk/test/catch_in_noexcept.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++98, c++03 +// UNSUPPORTED: c++98, c++03, libcxxabi-no-exceptions #include #include Index: libcxxabi/trunk/test/catch_member_data_pointer_01.pass.cpp =================================================================== --- libcxxabi/trunk/test/catch_member_data_pointer_01.pass.cpp +++ libcxxabi/trunk/test/catch_member_data_pointer_01.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include struct A Index: libcxxabi/trunk/test/catch_member_function_pointer_01.pass.cpp =================================================================== --- libcxxabi/trunk/test/catch_member_function_pointer_01.pass.cpp +++ libcxxabi/trunk/test/catch_member_function_pointer_01.pass.cpp @@ -10,6 +10,7 @@ // 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: libcxxabi-no-exceptions #include struct A Index: libcxxabi/trunk/test/catch_member_pointer_nullptr.pass.cpp =================================================================== --- libcxxabi/trunk/test/catch_member_pointer_nullptr.pass.cpp +++ libcxxabi/trunk/test/catch_member_pointer_nullptr.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #if __has_feature(cxx_nullptr) Index: libcxxabi/trunk/test/catch_multi_level_pointer.pass.cpp =================================================================== --- libcxxabi/trunk/test/catch_multi_level_pointer.pass.cpp +++ libcxxabi/trunk/test/catch_multi_level_pointer.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: libcxxabi/trunk/test/catch_pointer_nullptr.pass.cpp =================================================================== --- libcxxabi/trunk/test/catch_pointer_nullptr.pass.cpp +++ libcxxabi/trunk/test/catch_pointer_nullptr.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++98, c++03 +// UNSUPPORTED: c++98, c++03, libcxxabi-no-exceptions #include #include Index: libcxxabi/trunk/test/catch_pointer_reference.pass.cpp =================================================================== --- libcxxabi/trunk/test/catch_pointer_reference.pass.cpp +++ libcxxabi/trunk/test/catch_pointer_reference.pass.cpp @@ -25,6 +25,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: libcxxabi/trunk/test/catch_ptr.pass.cpp =================================================================== --- libcxxabi/trunk/test/catch_ptr.pass.cpp +++ libcxxabi/trunk/test/catch_ptr.pass.cpp @@ -13,6 +13,8 @@ check against. It also checks that virtual bases work properly */ +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: libcxxabi/trunk/test/catch_ptr_02.pass.cpp =================================================================== --- libcxxabi/trunk/test/catch_ptr_02.pass.cpp +++ libcxxabi/trunk/test/catch_ptr_02.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #if __cplusplus < 201103L Index: libcxxabi/trunk/test/cxa_bad_cast.pass.cpp =================================================================== --- libcxxabi/trunk/test/cxa_bad_cast.pass.cpp +++ libcxxabi/trunk/test/cxa_bad_cast.pass.cpp @@ -0,0 +1,55 @@ +//===----------------------- cxa_bad_cast.pass.cpp ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +#include +#include +#include +#include +#include + +class Base { + virtual void foo() {}; +}; + +class Derived : public Base {}; + +Derived &test_bad_cast(Base b) { + return dynamic_cast(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 LIBCXXABI_HAS_NO_EXCEPTIONS + try { +#endif + Derived &d = test_bad_cast(gB); + assert(false); +#ifndef LIBCXXABI_HAS_NO_EXCEPTIONS + } catch (std::bad_cast) { + // success + return 0; + } catch (...) { + assert(false); + } +#endif + + // failure, restore the default terminate handler and fire + std::set_terminate(default_handler); + std::terminate(); +} Index: libcxxabi/trunk/test/cxa_bad_typeid.pass.cpp =================================================================== --- libcxxabi/trunk/test/cxa_bad_typeid.pass.cpp +++ libcxxabi/trunk/test/cxa_bad_typeid.pass.cpp @@ -0,0 +1,55 @@ +//===----------------------- cxa_bad_typeid.pass.cpp ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===------------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +#include +#include +#include +#include +#include +#include +#include + +class Base { + virtual void foo() {}; +}; + +class Derived : public Base {}; + +std::string test_bad_typeid(Derived *p) { + typeid(*p).name(); +} + +void my_terminate() { std::cout << "A" << std::endl; exit(0); } + +int main () +{ + // swap-out the terminate handler + void (*default_handler)() = std::get_terminate(); + std::set_terminate(my_terminate); + +#ifndef LIBCXXABI_HAS_NO_EXCEPTIONS + try { +#endif + test_bad_typeid(nullptr); + assert(false); +#ifndef LIBCXXABI_HAS_NO_EXCEPTIONS + } catch (std::bad_typeid) { + // success + return 0; + } catch (...) { + assert(false); + } +#endif + + // failure, restore the default terminate handler and fire + std::set_terminate(default_handler); + std::terminate(); +} Index: libcxxabi/trunk/test/incomplete_type.sh.cpp =================================================================== --- libcxxabi/trunk/test/incomplete_type.sh.cpp +++ libcxxabi/trunk/test/incomplete_type.sh.cpp @@ -14,6 +14,8 @@ // incomplete flags set, equality can be tested by comparing the type_info // addresses. +// UNSUPPORTED: libcxxabi-no-exceptions + // RUN: %cxx %flags %compile_flags -c %s -o %t.one.o // RUN: %cxx %flags %compile_flags -c %s -o %t.two.o -DTU_ONE // RUN: %cxx %flags %t.one.o %t.two.o %link_flags -o %t.exe Index: libcxxabi/trunk/test/inherited_exception.pass.cpp =================================================================== --- libcxxabi/trunk/test/inherited_exception.pass.cpp +++ libcxxabi/trunk/test/inherited_exception.pass.cpp @@ -25,6 +25,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include struct Base { Index: libcxxabi/trunk/test/libcxxabi/test/config.py =================================================================== --- libcxxabi/trunk/test/libcxxabi/test/config.py +++ libcxxabi/trunk/test/libcxxabi/test/config.py @@ -35,12 +35,17 @@ def configure_features(self): super(Configuration, self).configure_features() + if not self.get_lit_bool('enable_exceptions', True): + self.config.available_features.add('libcxxabi-no-exceptions') if self.get_lit_bool('thread_atexit', True): self.config.available_features.add('thread_atexit') def configure_compile_flags(self): self.cxx.compile_flags += ['-DLIBCXXABI_NO_TIMER'] - self.cxx.compile_flags += ['-funwind-tables'] + if self.get_lit_bool('enable_exceptions', True): + self.cxx.compile_flags += ['-funwind-tables'] + else: + self.cxx.compile_flags += ['-fno-exceptions', '-DLIBCXXABI_HAS_NO_EXCEPTIONS'] if not self.get_lit_bool('enable_threads', True): self.cxx.compile_flags += ['-DLIBCXXABI_HAS_NO_THREADS=1'] super(Configuration, self).configure_compile_flags() Index: libcxxabi/trunk/test/lit.site.cfg.in =================================================================== --- libcxxabi/trunk/test/lit.site.cfg.in +++ libcxxabi/trunk/test/lit.site.cfg.in @@ -16,6 +16,7 @@ config.thread_atexit = "@LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL@" config.libcxxabi_shared = "@LIBCXXABI_ENABLE_SHARED@" config.enable_shared = "@LIBCXX_ENABLE_SHARED@" +config.enable_exceptions = "@LIBCXXABI_ENABLE_EXCEPTIONS@" # Let the main config do the real work. lit_config.load_config(config, "@LIBCXXABI_SOURCE_DIR@/test/lit.cfg") Index: libcxxabi/trunk/test/noexception1.pass.cpp =================================================================== --- libcxxabi/trunk/test/noexception1.pass.cpp +++ libcxxabi/trunk/test/noexception1.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------- noexception1.pass.cpp ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 +// REQUIRES: libcxxabi-no-exceptions + +#include +#include +#include +#include + +// namespace __cxxabiv1 { +// void __cxa_increment_exception_refcount(void *thrown_object) throw(); +// } + +unsigned gCounter = 0; + +void my_terminate() { exit(0); } + +int main () +{ + // should not call std::terminate() + __cxxabiv1::__cxa_increment_exception_refcount(nullptr); + + std::set_terminate(my_terminate); + + // should call std::terminate() + __cxxabiv1::__cxa_increment_exception_refcount((void*) &gCounter); + assert(false); + + return 0; +} Index: libcxxabi/trunk/test/noexception2.pass.cpp =================================================================== --- libcxxabi/trunk/test/noexception2.pass.cpp +++ libcxxabi/trunk/test/noexception2.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------- noexception2.pass.cpp ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 +// REQUIRES: libcxxabi-no-exceptions + +#include +#include +#include +#include + +// namespace __cxxabiv1 { +// void __cxa_decrement_exception_refcount(void *thrown_object) throw(); +// } + +unsigned gCounter = 0; + +void my_terminate() { exit(0); } + +int main () +{ + // should not call std::terminate() + __cxxabiv1::__cxa_decrement_exception_refcount(nullptr); + + std::set_terminate(my_terminate); + + // should call std::terminate() + __cxxabiv1::__cxa_decrement_exception_refcount((void*) &gCounter); + assert(false); + + return 0; +} Index: libcxxabi/trunk/test/noexception3.pass.cpp =================================================================== --- libcxxabi/trunk/test/noexception3.pass.cpp +++ libcxxabi/trunk/test/noexception3.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------- noexception3.pass.cpp ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 +// REQUIRES: libcxxabi-no-exceptions + +#include +#include +#include +#include + +// namespace __cxxabiv1 { +// void __cxa_rethrow_primary_exception(void* thrown_object); +// } + +unsigned gCounter = 0; + +void my_terminate() { exit(0); } + +int main () +{ + // should not call std::terminate() + __cxxabiv1::__cxa_rethrow_primary_exception(nullptr); + + std::set_terminate(my_terminate); + + // should call std::terminate() + __cxxabiv1::__cxa_rethrow_primary_exception((void*) &gCounter); + assert(false); + + return 0; +} Index: libcxxabi/trunk/test/noexception4.pass.cpp =================================================================== --- libcxxabi/trunk/test/noexception4.pass.cpp +++ libcxxabi/trunk/test/noexception4.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------- noexception4.pass.cpp ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: libcxxabi-no-exceptions + +#include +#include +#include + +// namespace __cxxabiv1 { +// void *__cxa_current_primary_exception() throw(); +// extern bool __cxa_uncaught_exception () throw(); +// extern unsigned int __cxa_uncaught_exceptions() throw(); +// } + +int main () +{ + // Trivially + assert(nullptr == __cxxabiv1::__cxa_current_primary_exception()); + assert(!__cxxabiv1::__cxa_uncaught_exception()); + assert(0 == __cxxabiv1::__cxa_uncaught_exceptions()); + return 0; +} Index: libcxxabi/trunk/test/test_aux_runtime.pass.cpp =================================================================== --- libcxxabi/trunk/test/test_aux_runtime.pass.cpp +++ libcxxabi/trunk/test/test_aux_runtime.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include Index: libcxxabi/trunk/test/test_aux_runtime_op_array_new.pass.cpp =================================================================== --- libcxxabi/trunk/test/test_aux_runtime_op_array_new.pass.cpp +++ libcxxabi/trunk/test/test_aux_runtime_op_array_new.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include Index: libcxxabi/trunk/test/test_guard.pass.cpp =================================================================== --- libcxxabi/trunk/test/test_guard.pass.cpp +++ libcxxabi/trunk/test/test_guard.pass.cpp @@ -41,6 +41,7 @@ // When initialization fails, ensure that we try to initialize it again next // time. namespace test2 { +#ifndef LIBCXXABI_HAS_NO_EXCEPTIONS static int run_count = 0; int increment() { ++run_count; @@ -58,6 +59,9 @@ helper(); assert(run_count == 2); } +#else + void test() {} +#endif } // Check that we can initialize a second value while initializing a first. Index: libcxxabi/trunk/test/test_vector1.pass.cpp =================================================================== --- libcxxabi/trunk/test/test_vector1.pass.cpp +++ libcxxabi/trunk/test/test_vector1.pass.cpp @@ -47,8 +47,19 @@ int gConstructorThrowTarget; int gDestructorCounter; int gDestructorThrowTarget; -void throw_construct ( void *p ) { if ( gConstructorCounter == gConstructorThrowTarget ) throw 1; ++gConstructorCounter; } -void throw_destruct ( void *p ) { if ( ++gDestructorCounter == gDestructorThrowTarget ) throw 2; } +void throw_construct ( void *p ) { +#ifndef LIBCXXABI_HAS_NO_EXCEPTIONS + if ( gConstructorCounter == gConstructorThrowTarget ) + throw 1; + ++gConstructorCounter; +#endif +} +void throw_destruct ( void *p ) { +#ifndef LIBCXXABI_HAS_NO_EXCEPTIONS + if ( ++gDestructorCounter == gDestructorThrowTarget ) + throw 2; +#endif +} #if __cplusplus >= 201103L # define CAN_THROW noexcept(false) @@ -146,6 +157,7 @@ return retVal; } +#ifndef LIBCXXABI_HAS_NO_EXCEPTIONS // Make sure the constructors and destructors are matched int test_exception_in_constructor ( ) { int retVal = 0; @@ -202,7 +214,9 @@ return retVal; } +#endif +#ifndef LIBCXXABI_HAS_NO_EXCEPTIONS // Make sure the constructors and destructors are matched int test_exception_in_destructor ( ) { int retVal = 0; @@ -253,12 +267,15 @@ return retVal; } +#endif int main ( int argc, char *argv [] ) { int retVal = 0; retVal += test_empty (); retVal += test_counted (); +#ifndef LIBCXXABI_HAS_NO_EXCEPTIONS retVal += test_exception_in_constructor (); retVal += test_exception_in_destructor (); +#endif return retVal; } Index: libcxxabi/trunk/test/test_vector2.pass.cpp =================================================================== --- libcxxabi/trunk/test/test_vector2.pass.cpp +++ libcxxabi/trunk/test/test_vector2.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include "cxxabi.h" #include Index: libcxxabi/trunk/test/test_vector3.pass.cpp =================================================================== --- libcxxabi/trunk/test/test_vector3.pass.cpp +++ libcxxabi/trunk/test/test_vector3.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include "cxxabi.h" #include Index: libcxxabi/trunk/test/uncaught_exceptions.pass.cpp =================================================================== --- libcxxabi/trunk/test/uncaught_exceptions.pass.cpp +++ libcxxabi/trunk/test/uncaught_exceptions.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: libcxxabi/trunk/test/unwind_01.pass.cpp =================================================================== --- libcxxabi/trunk/test/unwind_01.pass.cpp +++ libcxxabi/trunk/test/unwind_01.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include struct A Index: libcxxabi/trunk/test/unwind_02.pass.cpp =================================================================== --- libcxxabi/trunk/test/unwind_02.pass.cpp +++ libcxxabi/trunk/test/unwind_02.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include struct A Index: libcxxabi/trunk/test/unwind_03.pass.cpp =================================================================== --- libcxxabi/trunk/test/unwind_03.pass.cpp +++ libcxxabi/trunk/test/unwind_03.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: libcxxabi/trunk/test/unwind_04.pass.cpp =================================================================== --- libcxxabi/trunk/test/unwind_04.pass.cpp +++ libcxxabi/trunk/test/unwind_04.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: libcxxabi/trunk/test/unwind_05.pass.cpp =================================================================== --- libcxxabi/trunk/test/unwind_05.pass.cpp +++ libcxxabi/trunk/test/unwind_05.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: libcxxabi/trunk/test/unwind_06.pass.cpp =================================================================== --- libcxxabi/trunk/test/unwind_06.pass.cpp +++ libcxxabi/trunk/test/unwind_06.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include