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

Reply via email to