From 6f4842e725ea6b571440fcba248cb47d3c6a18ab Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Mon, 23 Feb 2026 11:15:24 +0100 Subject: [PATCH] [CPyCppyy] Add wchar_t*_Nonnull converter for libc++ std::wstring ctors Apple's libc++ headers (especially in newer macOS/Xcode SDKs) annotate some `std::basic_string` constructors with Clang nullability qualifiers (e.g. `const wchar_t* _Nonnull`). The cppyy backend currently preserves these qualifiers in the type spelling, so the existing `wchar_t*` converter does not match `wchar_t*_Nonnull`. This breaks Python string to std::wstring conversions and causes STL string tests to fail on macOS. Add an explicit converter mapping for `wchar_t*_Nonnull` to reuse the existing WCStringConverter. A more general solution would be to strip/normalize Clang attributes during type matching. (cherry picked from commit 43a8eff5b80795d891adbdca9831abf6d5fcdc01) --- bindings/pyroot/cppyy/CPyCppyy/src/Converters.cxx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/bindings/pyroot/cppyy/CPyCppyy/src/Converters.cxx b/bindings/pyroot/cppyy/CPyCppyy/src/Converters.cxx index 330afbd96f9ce..e63d2545e3d34 100644 --- a/bindings/pyroot/cppyy/CPyCppyy/src/Converters.cxx +++ b/bindings/pyroot/cppyy/CPyCppyy/src/Converters.cxx @@ -3641,6 +3641,17 @@ static struct InitConvFactories_t { gf["char[]"] = (cf_t)+[](cdims_t d) { return new NonConstCStringArrayConverter{d, true}; }; gf["signed char*"] = gf["char*"]; gf["wchar_t*"] = (cf_t)+[](cdims_t) { return new WCStringConverter{}; }; + // TODO: The libc++ library that is used most prominently by Apple for + // macOS is using the _Nonnull Clang attribute for some of its string + // constructors (_LIBCPP_DIAGNOSE_NULLPTR is a preprocessor macro that + // resolves to _Nullable). The cppyy backend doesn't strip away such Clang + // attributes, so the wchar_t* converter fails to match. To make the + // construction of std::wstring work on macOS, we are explicitly creating + // a converter for the wchar_t*_Nonnull type here, but we should try to + // find a more general solution for dealing with Clang attributes. + // [1] https://clang.llvm.org/docs/AttributeReference.html#id656 + // [2] https://github.com/llvm/llvm-project/blob/2078da43e25a4623cab2d0d60decddf709aaea28/libcxx/include/string#L1061 + gf["wchar_t*_Nonnull"] = (cf_t)+[](cdims_t) { return new WCStringConverter{}; }; gf["char16_t*"] = (cf_t)+[](cdims_t) { return new CString16Converter{}; }; gf["char16_t[]"] = (cf_t)+[](cdims_t d) { return new CString16Converter{dims2stringsz(d)}; }; gf["char32_t*"] = (cf_t)+[](cdims_t) { return new CString32Converter{}; };