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) @@ -348,5 +356,14 @@ "LIBCXXABI_ENABLE_SHARED is on, no check target will be " "available!") else() - add_subdirectory(test) + # libc++abi tests are mostly exceptions related. The only reason we want to + # build libc++abi without exceptions is to support the -fno-exceptions libc++ + # build. + if (NOT LIBCXXABI_ENABLE_EXCEPTIONS) + message(WARNING "The libc++abi tests are currently only valid when " + "LIBCXXABI_ENABLE_EXCEPTIONS is on, no check target will be " + "available!") + else() + add_subdirectory(test) + endif() endif() 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 + std::terminate(); +#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); }