This teaches IRGen to only emit a lifetime operation (retain or release) for a C++ foreign reference type if the pointer is not `nullptr`.
Previously the compiler would in some cases emit a release call for `nullptr`, which breaks the assumption that the argument to a custom release function is `_Nonnull`. For instance:
```
var globalOptional: MyRefType? = nil
func foo() { globalOptional = MyRefType.create() }
```
When emitting IR for the assignment operation to `globalOptional`, the compiler would emit code to first retrieve the existing value of `globalOptional` and release it. If the value is `nil`, it does not need to be released.
rdar://97532642
This fixes a crash in SILGen when calling a C++ subscript that has an unnamed parameter from Swift.
The parameters from a C++ `operator[]` get carried over to the synthesized Swift subscript. If the Swift parameter has no name, there is no way to refer to it in SIL. However, the synthesized subscript accessor needs to pass this parameter to C++.
This change makes sure that we give a name to the Swift parameter if there isn't already a name on the C++ side.
rdar://83163841
This adds a test that ensures that a symbolic interface for a C++ module will include these features:
* move-only types
* virtual methods
Default arguments are already tested.
rdar://125816549
C++ pointer type `T*` is generally imported as `Unsafe(Mutable)Pointer<T>`. However, if `T` is non-copyable in Swift (e.g. it has a deleted C++ copy constructor), using `UnsafePointer<T>` type requires noncopyable generics to be enabled.
This was causing assertion failures when building SwiftCompilerSources in https://github.com/apple/swift/pull/72912.
When Swift imports C structs, it synthesizes an initializer that takes no arguments and zero-initializes the C struct.
When C++ interop is enabled, Clang treats all C structs as if they were C++ structs. This means that some of the C structs will get a default constructor implicitly generated by Clang. This implicit default constructor will not zero-initialize trivial fields of the struct.
This is a common source of confusion and subtle bugs for developers who try to enable C++ interop in existing projects that use C interop and rely on zero-initialization of C structs.
rdar://115909532
This fixes an assertion failure when building certain projects for arm64e with `-use-clang-function-types` Swift compiler flag:
```
Expected non-null Clang type for @convention(c)/@convention(block) function but found nullptr
```
rdar://121227452
Clang is using C++17 standard version by default since Clang 16.
Swift’s ClangImporter should do the same, to make sure that clients who run clang and then swiftc without explicit std version see consistent behavior.
rdar://125777068
The header was defining a function, the function created a lambda, and
the lambda was transformed into a `std::function`. This transformation
is incorrect because the function scope does not have linkage, so the
instantiated types will not have linkage either, causing the error
below.
```
.../include/c++/11.2.0/bits/invoke.h:104:5:
error: function 'std::__invoke_r<int, (lambda at .../swift/test/Interop/Cxx/stdlib/Inputs/std-function.h:9:10) &, int>' is used but not defined in this translation unit, and cannot be defined in any other translation unit because its type does not have linkage
102 │ template<typename _Res, typename _Callable, typename... _Args>
103 │ constexpr enable_if_t<is_invocable_r_v<_Res, _Callable,
_Args...>, _Res>
104 │ __invoke_r(_Callable&& __fn, _Args&&... __args)
│ ╰─ error: function 'std::__invoke_r<int, (lambda at .../swift/test/Interop/Cxx/stdlib/Inputs/std-function.h:9:10) &, int>' is used but not defined in this translation unit, and cannot be defined in any other translation unit because its type does not have linkage
105 │ noexcept(is_nothrow_invocable_r_v<_Res, _Callable,
_Args...>)
106 │ {
}
```
Declaring the function `inline` forces each TU to have their own copies
of the function, which avoids the instantiated templates from being in a
different TU than the one using them.
The header would not have worked in a normal C++ program, since none of
the functions declare linkage, they would have been defined in each TU
that included the header and it would fail linking as soon as two of
those TU tried to be linked together. Declaring the functions `inline`
avoids the problem (a more normal header, only with declarations, would
also worked).
The test was relying on UnsafeMutablePointer (UMP) not having a Copyable
requirement. Those Copyable requirements are more prominent when using
the new infrastructure for noncopyable types. Since UMP is planned to
have `~Copyable` on its generic parameter quite soon, this shouldn't
remain broken for too long.
This adds a new implementation of virtual method dispatch that handles reference types correctly.
Previously, for all C++ types an invocation of a virtual method would actually get dispatched statically. For value types this is expected and matches what C++ does because of slicing. For reference types, however, this is incorrect, we should do dynamic dispatch.
rdar://123852577
Fix a bug in expandExternalSignatureTypes where it wasn't annotating a function call parameter type with sret when the result was being returned indirectly.
The bug was causing calls to ObjC methods that return their results indirectly to crash.
Additionally, fix the return type for C++ constructors computed in expandExternalSignatureTypes. Previously, the return type was always void even on targets that require constructors to return this (e.g., Apple arm64), which was causing C++ constructor thunks to be emitted needlessly.
Resolves rdar://121618707