[libcxx-commits] [libcxx] [libc++] Fix std::make_exception_ptr interaction with ObjC (PR #135386)

James Y Knight via libcxx-commits libcxx-commits at lists.llvm.org
Sat Jul 5 20:35:23 PDT 2025


================
@@ -118,14 +113,42 @@ _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
     __cxxabiv1::__cxa_free_exception(__ex);
     return current_exception();
   }
-#    else
+}
+
+template <class _Ep>
+_LIBCPP_HIDE_FROM_ABI exception_ptr __make_exception_ptr_via_throw(_Ep& __e) _NOEXCEPT {
   try {
     throw __e;
   } catch (...) {
     return current_exception();
   }
+}
+
+template <class _Ep>
+_LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
+#  if _LIBCPP_HAS_EXCEPTIONS
+  // Objective-C exceptions are thrown via pointer. When throwing an Objective-C exception,
+  // Clang generates a call to `objc_exception_throw` instead of the usual `__cxa_throw`.
+  // That function creates an exception with a special Objective-C typeinfo instead of
+  // the usual C++ typeinfo, since that is needed to implement the behavior documented
+  // at [1]).
+  //
+  // Because of this special behavior, we can't create an exception via `__cxa_init_primary_exception`
+  // for Objective-C exceptions, otherwise we'd bypass `objc_exception_throw`. See https://llvm.org/PR135089.
+  //
+  // [1]:
+  // https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Exceptions/Articles/Exceptions64Bit.html
+  if constexpr (is_pointer<_Ep>::value) {
----------------
jyknight wrote:

Right; it needs an ifdef. That shouldn't cause issues -- I think -- because the template arg cannot be an ObjC type and thus convertible to id if it's not an objc file. The reason not to do it was just itrofimow's feeling it was too complicated. It may well be, I don't have strong feelings here. So probably best to just leave it the way you have it now.

https://github.com/llvm/llvm-project/pull/135386


More information about the libcxx-commits mailing list