Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[libc++] fix std::make_exception_ptr interaction with ObjC #135386

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
Loading
from

Conversation

itrofimow
Copy link
Contributor

@itrofimow itrofimow commented Apr 11, 2025

Clang treats throwing/catching ObjC types differently from C++ types, and omitting the throw in std::make_exception_ptr breaks ObjC invariants about how types are thrown/caught.

Fixes #135089

@itrofimow itrofimow changed the title fix std::make_exception_ptr interaction with ObjC [libc++] fix std::make_exception_ptr interaction with ObjC Apr 14, 2025
@itrofimow itrofimow marked this pull request as ready for review April 14, 2025 19:04
@itrofimow itrofimow requested a review from a team as a code owner April 14, 2025 19:04
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Apr 14, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 14, 2025

@llvm/pr-subscribers-libcxx

Author: None (itrofimow)

Changes

Clang treats throwing/catching ObjC types differently from C++ types, and omitting the throw in std::make_exception_ptr breaks ObjC invariants about how types are thrown/caught


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

1 Files Affected:

  • (modified) libcxx/include/__exception/exception_ptr.h (+2-1)
diff --git a/libcxx/include/__exception/exception_ptr.h b/libcxx/include/__exception/exception_ptr.h
index dac5b00b57fe3..167aa4d9b367a 100644
--- a/libcxx/include/__exception/exception_ptr.h
+++ b/libcxx/include/__exception/exception_ptr.h
@@ -92,7 +92,8 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
 template <class _Ep>
 _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
 #  if _LIBCPP_HAS_EXCEPTIONS
-#    if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION && __cplusplus >= 201103L
+  // Clang treats throwing ObjC types differently, and we have to preserve original throw-ing behavior
+#    if !defined(__OBJC__) && _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION && __cplusplus >= 201103L
   using _Ep2 = __decay_t<_Ep>;
 
   void* __ex = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ep));

@jyknight
Copy link
Member

It's not great to condition only on __OBJC__ preprocessor define, since that'll create a potential ODR issue for std::make_exception_ptr on a C++ type, when you're mixing a TU built with C++ and another TU built with ObjC++ in the same program (which, everyone is).

If you switch to the throw impl only for ObjC object-pointers, that stops being a problem, as an ObjC object pointer type cannot exist in a non-ObjC++ TU.

As a refinement to my suggestion on the issue, I think std::is_pointer_v<_Ep> && std::is_convertible_v<_Ep, id> would be better (so as to not accidentally trigger on a C++ value with a user-defined conversion operator id()).

@jyknight
Copy link
Member

Are you still planning to update this patch?

@itrofimow
Copy link
Contributor Author

Hi! Yes, sorry, just got back to office

I was thinking, wouldn't just std::is_pointer_v<_Ep> condition be better it terms of readability?
After all, this is just an optimization, and given that people very seldom create exception pointers from pointers, it shouldn't be that much of a performance hit, and the less odd conditions we have here the better

@jyknight
Copy link
Member

You mean without the OBJC ifdef? I think that would be OK. But IMO it's not actually an improvement, because the condition is no longer clearly connected with the actual reason for the existence of the alternate codepath.

@itrofimow
Copy link
Contributor Author

I don't think CI failure has to do with these changes, @jyknight could you please have a look?

using _Ep2 = __decay_t<_Ep>;

void* __ex = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ep));
# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION && __cplusplus >= 201703L
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should really be _LIBCPP_STD_VER >= 17. Also, why did this change from C++11 to C++17?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is about language-level features rather than libc++ features: c++11 or higher was required for the lambda to compile; c++17 or higher is now required for if constexpr

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[libc++] [libc++abi] Regression: std::make_exception_ptr breaks catching ObjC objects on rethrow
4 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.