Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ 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) @@ -241,13 +242,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() # Assert string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE) Index: src/cxa_aux_runtime.cpp =================================================================== --- src/cxa_aux_runtime.cpp +++ 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: src/cxa_handlers.cpp =================================================================== --- src/cxa_handlers.cpp +++ 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: src/cxa_new_delete.cpp =================================================================== --- src/cxa_new_delete.cpp +++ 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: src/cxa_personality.cpp =================================================================== --- src/cxa_personality.cpp +++ src/cxa_personality.cpp @@ -1201,9 +1201,12 @@ t_handler = std::get_terminate(); u_handler = std::get_unexpected(); } +#ifndef _LIBCXXABI_NO_EXCEPTIONS try { +#endif std::__unexpected(u_handler); +#ifndef _LIBCXXABI_NO_EXCEPTIONS } catch (...) { @@ -1292,6 +1295,7 @@ } } } +#endif std::__terminate(t_handler); } Index: test/CMakeLists.txt =================================================================== --- test/CMakeLists.txt +++ 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: test/backtrace_test.pass.cpp =================================================================== --- test/backtrace_test.pass.cpp +++ test/backtrace_test.pass.cpp @@ -19,11 +19,13 @@ } void call3_throw(size_t* ntraced) { +#ifdef LIBCXXABI_ENABLE_EXCEPTIONS try { _Unwind_Backtrace(trace_function, ntraced); } catch (...) { assert(false); } +#endif } void call3_nothrow(size_t* ntraced) { @@ -48,15 +50,19 @@ call1(¬hrow_ntraced, false); +#ifdef LIBCXXABI_ENABLE_EXCEPTIONS try { call1(&throw_ntraced, true); } catch (...) { assert(false); } +#endif // Different platforms (and different runtimes) will unwind a different number // of times, so we can't make any better assumptions than this. assert(nothrow_ntraced > 1); +#ifdef LIBCXXABI_ENABLE_EXCEPTIONS assert(throw_ntraced == nothrow_ntraced); // Make sure we unwind through catch +#endif return 0; } Index: test/catch_array_01.pass.cpp =================================================================== --- test/catch_array_01.pass.cpp +++ 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: test/catch_array_02.pass.cpp =================================================================== --- test/catch_array_02.pass.cpp +++ 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: test/catch_class_01.pass.cpp =================================================================== --- test/catch_class_01.pass.cpp +++ test/catch_class_01.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: test/catch_class_02.pass.cpp =================================================================== --- test/catch_class_02.pass.cpp +++ test/catch_class_02.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: test/catch_class_03.pass.cpp =================================================================== --- test/catch_class_03.pass.cpp +++ test/catch_class_03.pass.cpp @@ -13,6 +13,8 @@ check against. */ +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: test/catch_class_04.pass.cpp =================================================================== --- test/catch_class_04.pass.cpp +++ 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: test/catch_const_pointer_nullptr.pass.cpp =================================================================== --- test/catch_const_pointer_nullptr.pass.cpp +++ test/catch_const_pointer_nullptr.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #if __has_feature(cxx_nullptr) Index: test/catch_function_01.pass.cpp =================================================================== --- test/catch_function_01.pass.cpp +++ 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: test/catch_function_02.pass.cpp =================================================================== --- test/catch_function_02.pass.cpp +++ 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: test/catch_in_noexcept.pass.cpp =================================================================== --- test/catch_in_noexcept.pass.cpp +++ 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: test/catch_member_data_pointer_01.pass.cpp =================================================================== --- test/catch_member_data_pointer_01.pass.cpp +++ test/catch_member_data_pointer_01.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include struct A Index: test/catch_member_function_pointer_01.pass.cpp =================================================================== --- test/catch_member_function_pointer_01.pass.cpp +++ 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: test/catch_member_pointer_nullptr.pass.cpp =================================================================== --- test/catch_member_pointer_nullptr.pass.cpp +++ test/catch_member_pointer_nullptr.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #if __has_feature(cxx_nullptr) Index: test/catch_multi_level_pointer.pass.cpp =================================================================== --- test/catch_multi_level_pointer.pass.cpp +++ test/catch_multi_level_pointer.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: test/catch_pointer_nullptr.pass.cpp =================================================================== --- test/catch_pointer_nullptr.pass.cpp +++ 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: test/catch_pointer_reference.pass.cpp =================================================================== --- test/catch_pointer_reference.pass.cpp +++ test/catch_pointer_reference.pass.cpp @@ -25,6 +25,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: test/catch_ptr.pass.cpp =================================================================== --- test/catch_ptr.pass.cpp +++ 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: test/catch_ptr_02.pass.cpp =================================================================== --- test/catch_ptr_02.pass.cpp +++ test/catch_ptr_02.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #if __cplusplus < 201103L Index: test/incomplete_type.sh.cpp =================================================================== --- test/incomplete_type.sh.cpp +++ 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: test/inherited_exception.pass.cpp =================================================================== --- test/inherited_exception.pass.cpp +++ test/inherited_exception.pass.cpp @@ -25,6 +25,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include struct Base { Index: test/libcxxabi/test/config.py =================================================================== --- test/libcxxabi/test/config.py +++ 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', '-DLIBCXXABI_ENABLE_EXCEPTIONS'] + else: + self.cxx.compile_flags += ['-fno-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: test/lit.site.cfg.in =================================================================== --- test/lit.site.cfg.in +++ 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: test/test_aux_runtime.pass.cpp =================================================================== --- test/test_aux_runtime.pass.cpp +++ test/test_aux_runtime.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include Index: test/test_aux_runtime_op_array_new.pass.cpp =================================================================== --- test/test_aux_runtime_op_array_new.pass.cpp +++ test/test_aux_runtime_op_array_new.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include Index: test/test_guard.pass.cpp =================================================================== --- test/test_guard.pass.cpp +++ test/test_guard.pass.cpp @@ -41,6 +41,7 @@ // When initialization fails, ensure that we try to initialize it again next // time. namespace test2 { +#ifdef LIBCXXABI_ENABLE_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: test/test_vector1.pass.cpp =================================================================== --- test/test_vector1.pass.cpp +++ test/test_vector1.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include "cxxabi.h" #include Index: test/test_vector2.pass.cpp =================================================================== --- test/test_vector2.pass.cpp +++ test/test_vector2.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include "cxxabi.h" #include Index: test/test_vector3.pass.cpp =================================================================== --- test/test_vector3.pass.cpp +++ test/test_vector3.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include "cxxabi.h" #include Index: test/uncaught_exceptions.pass.cpp =================================================================== --- test/uncaught_exceptions.pass.cpp +++ test/uncaught_exceptions.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: test/unwind_01.pass.cpp =================================================================== --- test/unwind_01.pass.cpp +++ test/unwind_01.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include struct A Index: test/unwind_02.pass.cpp =================================================================== --- test/unwind_02.pass.cpp +++ test/unwind_02.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include struct A Index: test/unwind_03.pass.cpp =================================================================== --- test/unwind_03.pass.cpp +++ test/unwind_03.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: test/unwind_04.pass.cpp =================================================================== --- test/unwind_04.pass.cpp +++ test/unwind_04.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: test/unwind_05.pass.cpp =================================================================== --- test/unwind_05.pass.cpp +++ test/unwind_05.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include Index: test/unwind_06.pass.cpp =================================================================== --- test/unwind_06.pass.cpp +++ test/unwind_06.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcxxabi-no-exceptions + #include #include #include