rmaprath created this revision. rmaprath added reviewers: bcraig, jroelofs, EricWF. rmaprath added a subscriber: cfe-commits.
Support for building a -fno-exceptions libc++ variant was reinstated recently. However, some of the standard library functions like `std::terminate()` are currently spread across lib++ and libc++abi, making the -fno-exceptions libc++ variant useless when those functions are used (as they pull in all the exceptions machinery that we are trying to get rid of in the final image). This patch makes it possilbe to also build libc++abi with -fno-exceptions so that functions like `std::terminate()` can be used in a no-exceptions environment. Most of the sources are already correctly setup to support a -fno-exceptions build, I just filled in the missing bits. If there are no objections, I will get this committed over the weekend. http://reviews.llvm.org/D20677 Files: CMakeLists.txt src/cxa_aux_runtime.cpp src/cxa_handlers.cpp src/cxa_new_delete.cpp src/cxa_personality.cpp
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: 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_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_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: 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()
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits