Skip to content

Commit 779da64

Browse files
committed
Fix __split_buffer_pointer_layout compatibility with swift's C++ import
When the swift compiler generates a bridging module for importing C++ symbols, it instantiates all methods of the class template instances used by the symbols imported from C++. This is because it cannot determine which methods will be called from swift at that stage. This means that it may attempt to generate invalid instantiations (due to missing type traits) that would not be generated in a normal C++ build. The default constructor of `__split_buffer_pointer_layout` has this issue because it does not initialize `__alloc_` which may or may not be a reference depending on the `allocator_type` tempalte parameter. The initialization of class members that are references is mandatory. `vector` uses a reference type for the allocator and `deque` does not. Therefore, only `deque` is allowed to use the default constructor of `__split_buffer_pointer_layout`. When the swift compiler's C++ importer generates an instantiation of `std::vector`, it will also attempt to instantiate the default constructor of `__split_buffer_pointer_layout`, which fails to compile. This change fixes the issue by adding a `requires` clause to suppress the instantiation of the problematic constructor whenever its instatiation would be invalid. There are no tests included in this change because the `requires` statement has no observable effect on pure C++ builds. Test coverage will be automatically assured downstream in swift-project once it updates its fork of libc++.
1 parent 7afeea4 commit 779da64

File tree

2 files changed

+15
-2
lines changed

2 files changed

+15
-2
lines changed

libcxx/CREDITS.TXT

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ N: Andrew Morrow
112112
E: andrew.c.morrow@gmail.com
113113
D: Minor patches and Linux fixes.
114114

115+
N: Justin Novosad
116+
E: junov@google.com
117+
E: justin.novosad@gmail.com
118+
D: Minor fixes, Swift interoperability.
119+
115120
N: Michael Park
116121
E: mcypark@gmail.com
117122
D: Implementation of <variant>.

libcxx/include/__split_buffer

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
#include <__type_traits/integral_constant.h>
3131
#include <__type_traits/is_nothrow_assignable.h>
3232
#include <__type_traits/is_nothrow_constructible.h>
33+
#if _LIBCPP_STD_VER >= 20
34+
# include <__type_traits/is_reference.h>
35+
#endif
3336
#include <__type_traits/is_swappable.h>
3437
#include <__type_traits/is_trivially_destructible.h>
3538
#include <__type_traits/is_trivially_relocatable.h>
@@ -68,8 +71,13 @@ protected:
6871

6972
public:
7073
// Can't be defaulted due to _LIBCPP_COMPRESSED_PAIR not being an aggregate in C++03 and C++11.
71-
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer_pointer_layout() : __back_cap_(nullptr) {}
72-
74+
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer_pointer_layout()
75+
#if _LIBCPP_STD_VER >= 20
76+
// Prevents Swift compiler's C++ importer from implicitly instantiating this ctor when it's not supported.
77+
requires (!is_reference_v<allocator_type>)
78+
#endif
79+
: __back_cap_(nullptr) {}
80+
7381
_LIBCPP_CONSTEXPR_SINCE_CXX20
7482
_LIBCPP_HIDE_FROM_ABI explicit __split_buffer_pointer_layout(const allocator_type& __alloc)
7583
: __back_cap_(nullptr), __alloc_(__alloc) {}

0 commit comments

Comments
 (0)