Commit Graph

51 Commits

Author SHA1 Message Date
Gábor Horváth
e700c6b8d4 [6.2][cxx-interop] Support _LIBCPP_PREFERRED_OVERLOAD
Explanation: Some functions are implemented both in libc and libc++.
Clang uses the enable_if attribute to resolve otherwise ambiguous
functions calls. This PR makes the name lookup aware of this attribute.
Issue: rdar://152192945
Risk: Low, only C/C++ APIs with enable_if attributes are affected.
Testing: Regression test added.
Original PR: #82019
Reviewer: @hnrklssn
2025-06-09 13:40:34 +01:00
John Hui
323e9f0b84 [cxx-interop] Fix assertion failure from unavailable NS_ENUM typedef
The NS_OPTIONS macro sometimes uses a pattern where it loosely
associates a typedef with an anonymous enum via a shared underlying
integer type (emphasis on "loosely"). The typedef is marked as
unavailable in Swift so as to not cause name ambiguity when we associate
the anonymous enum with said typedef. We use unavailability as
a heuristic during the import process, but that conflates NS_OPTIONS
with NS_ENUMs that can be marked as unavailable for entirely unrelated
reasons.

That in and of itself is fine, because the import logic is general
enough to handle both cases, but we have an assertion that seems to be
unaware of this scenario, and trips on unavailable NS_ENUMs. (In those
cases, the typedef points to the enum rather than the underlying integer
type.) This patch fixes the assertion to be resilient against such cases
by looking through the enum a typedef refers to.

rdar://150399978
(cherry picked from commit 80db05455f)
2025-05-21 18:54:42 -07:00
fahadnayyar
5ac1e63ad6 [6.2] [cxx-interop] Disabling should be annotated with SWIFT_RETURNS_(UN)RETAINED warning (#81390)
**Explanation**:
In Swift 6.1, we introduced warnings for C++ APIs returning
`SWIFT_SHARED_REFERENCE` types that lack the
`SWIFT_RETURNS_(UN)RETAINED` annotations. These warnings serve as a
reminder to annotate APIs, as the absence of these annotations can lead
to arbitrary assumptions about the ownership of returned
`SWIFT_SHARED_REFERENCE` values. This could result in both
use-after-free (memory safety) bugs and memory leaks.
We have received feedback from a few adopters indicating potential false
positive cases where these warnings are triggered. Consequently, we have
decided to disable these warnings in Swift 6.2 and re-qualify the
warnings on larger projects to ensure their effectiveness and eliminate
false positives.

- **Scope**: Disabling a previously shipped warning. There is no
likelihood of any source breakage or semantic alterations.
- **Issues**: rdar://150937617 , rdar://150800115
- **Original PRs**: N/A
- **Risk**: Low
- **Testing**: Lit test and adopted manually on a demo Xcode project
- **Reviewers**: N/A Our intention is to re-enable the warnings in later
beta releases of Swift 6.2 once we have stronger evidence of their
effectiveness on large codebases and proof that there are no false
positives.
2025-05-09 08:08:01 -07:00
Anthony Latsis
5e41794680 AST: Quote attributes more consistently in DiagnosticsSema.def 2025-04-23 19:18:08 +01:00
Egor Zhdan
83f3a2dc56 [cxx-interop] Re-enable a test for Obj-C compatibility
rdar://128544755
2025-03-07 15:00:41 +00:00
Egor Zhdan
2a2856fc84 Revert "[cxx-interop] Workaround name lookup issues with namespace simd"
This reverts commit c7021ae979.

The change triggers a compiler regression for some projects that rely on simd and enable C++ interop.

rdar://143352205
2025-01-23 16:55:07 +00:00
Erik Eckstein
34a68736ac tests: fix Interop/Cxx/objc-correctness/appkit-uikit.swift for iOS 2025-01-20 15:24:19 +01:00
Cassie Jones
7323a752b6 [cxx-interop] Workaround compiler error when importing AppKit/UIKit with C++ interop
The AppKit/UIKit overlay refers to symbols declared via NS_OPTIONS
macro, which is causing issues in C++ language mode due to the macro
definition being different. This teaches the module interface loader to
drop the C++ interop flag when rebuilding the AppKit and UIKit overlay
from its interface.

This is the same fix as #78636, but for different modules.

rdar://143033209
2025-01-16 15:19:23 -08:00
Cassie Jones
c7021ae979 [cxx-interop] Workaround name lookup issues with namespace simd
On Apple platforms, a system module `simd` declares a `namespace simd`
under `#if defined(__cplusplus)`. This namespace defines C++ overlays of
the simd types, but these types are already refined for Swift
separately, so it's not necessary to import this namespace.

This is the same issue previously encountered for the `os` module, work
around it in the same way.

rdar://143007477
2025-01-15 21:29:17 -08:00
Egor Zhdan
7537dac9b0 [cxx-interop] Fix a failing test
The API that is being used is not available on all versions of all platforms.

rdar://142973844
2025-01-15 18:14:59 +00:00
Egor Zhdan
dd11207b58 Merge pull request #78634 from swiftlang/egorzhdan/os-logger
[cxx-interop] Workaround name lookup issues with `namespace os`
2025-01-15 13:11:30 +00:00
Egor Zhdan
d72006e265 [cxx-interop] Workaround compiler error when importing CoreGraphics with C++ interop
The CoreGraphics overlay refers to symbols declared via `CF_OPTIONS` macro, which is causing issues in C++ language mode due to the macro definition being different.

This teaches the module interface loader to drop the C++ interop flag when rebuilding the CoreGraphics overlay from its interface.

rdar://142762174
2025-01-14 19:25:40 +00:00
Egor Zhdan
430809d35d [cxx-interop] Workaround name lookup issues with namespace os
On Apple platforms, a system module `os` declares a `namespace os` under `#if defined(__cplusplus)`. This causes ClangImporter to import it as `enum os` when C++ interop is enabled. This causes name lookup ambiguity (module os vs namespace os) which is resolved in namespace's favor, breaking existing usages.

rdar://119044493
2025-01-14 18:11:18 +00:00
Fahad Nayyar
69332f706f [cxx-interop] Diagnose ObjC APIs returning SWIFT_SHARED_REFERENCE types
rdar://142500663
2025-01-08 11:36:49 -08:00
Egor Zhdan
e5899ee167 [cxx-interop] Use fully-qualified type names of C++ template parameters
When importing C++ class template instantiations, Swift generates a type name for each instantiation. The generated names must be unique, since they are used for mangling.

If multiple different C++ types declare nested types with the same name, which are then used as template arguments, Swift was generating the same name for those template instantiations (e.g. `shared_ptr<Impl>` for different `Impl` types).

This change makes sure we use fully-qualified type names of template parameters when generating Swift type names for class template instantiations (e.g. `shared_ptr<MyNamespace.MyClass.Impl>`).

This fixes an assertion failure coming out of IRGen:
```
Assertion failed: (Buffer.empty() && "didn't claim all values out of buffer"), function ~ConstantInitBuilderBase, file ConstantInitBuilder.h, line 75.
```

rdar://141962480
2025-01-02 18:03:56 +00:00
Fahad Nayyar
426d471d1e [cxx-interop] Add support for SWIFT_RETURNS_(UN)RETAINED for ObjC APIs returning C++ FRT
rdar://135360972
2024-12-17 17:31:47 -08:00
Egor Zhdan
80cd6b0795 [cxx-interop] Remove redundant [extern_c] in tests
`[extern_c]` module attribute has no effect in these tests.
2024-10-04 16:50:21 +01:00
Akira Hatanaka
42bc49d3fe Add a new parameter convention @in_cxx for non-trivial C++ classes that are passed indirectly and destructed by the caller (#73019)
This corresponds to the parameter-passing convention of the Itanium C++
ABI, in which the argument is passed indirectly and possibly modified,
but not destroyed, by the callee.

@in_cxx is handled the same way as @in in callers and @in_guaranteed in
callees. OwnershipModelEliminator emits the call to destroy_addr that is
needed to destroy the argument in the caller.

rdar://122707697
2024-06-27 09:44:04 -07:00
Hamish Knight
bffb37e69f [test] Disable pthread_mutexattr_t.swift 2024-05-29 12:09:14 +01:00
Egor Zhdan
62c0a3325f [cxx-interop] Add test for an already-fixed IRGen crash
resolves https://github.com/apple/swift/issues/57308
2024-04-24 18:02:44 +01:00
Akira Hatanaka
b3f302b96b [IRGen] Fix a bug where an argument wasn't annotated with sret (#71459)
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
2024-02-22 14:14:47 -08:00
Egor Zhdan
be24236bea Revert "Revert "[cxx-interop] Look up NSNotificationName in C++ language mode properly""
This reverts commit 80448d2f1c.
2023-11-10 13:26:00 +00:00
Alex Lorenz
c2e15d6472 [cxx-interop] disallow use of non-trivial C++ types in @objc declarations
Even though such types can technically be represented in C++, Swift's @objc support does not support them

rdar://114163485
2023-10-18 17:49:13 -07:00
Egor Zhdan
041005af7c [cxx-interop] Use more correct type names in C++ template parameters
When importing a C++ class template instantiation, Swift translates the template parameter type names from C++ into their Swift equivalent.

For instance, `basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>>` gets imported as `basic_string<Scalar, char_traits<Scalar>, allocator<Scalar>>`: `wchar_t` is imported as `CWideChar`, which is a typealias for `Scalar` on most platforms including Darwin. Notice that Swift goes through the `CWideChar` typealias on the specific platform. Another instantiation `basic_string<uint32_t, char_traits<uint32_t>, allocator<uint32_t>>` also gets imported as `basic_string<Scalar, char_traits<Scalar>, allocator<Scalar>>`: `uint32_t` is also imported as `Scalar`. This is problematic because we have two distinct C++ types that have the same name in Swift.

This change makes sure Swift doesn't go through typealiases when emitting names of template parameters, so `wchar_t` would now get printed as `CWideChar`, `int` would get printed as `CInt`, etc.

This also encourages clients to use the correct type (`CInt`, `CWideChar`, etc) instead of relying on platform-specific typealiases.

rdar://115673622
2023-10-09 14:57:10 +01:00
Alex Lorenz
21fbd7a48f Revert "Revert "Revert "[cxx-interop] Import custom NS_OPTIONS correctly"""
This reverts commit f7c2257f51.
2023-09-28 18:47:19 -07:00
Alex Lorenz
59f86d71f2 Revert "[cxx-interop] Refactor: do not rely on Clang module importer being available"
This reverts commit 6a2f10a388.
2023-09-28 18:47:12 -07:00
Egor Zhdan
80448d2f1c Revert "[cxx-interop] Look up NSNotificationName in C++ language mode properly"
This reverts commit e956e8ac1d.
2023-09-25 20:14:00 +01:00
Egor Zhdan
6a2f10a388 [cxx-interop] Refactor: do not rely on Clang module importer being available
This makes sure that we can emit a pch from a C++ header that uses `CF_OPTIONS`.

rdar://112225263
2023-09-18 21:54:11 +01:00
Egor Zhdan
f7c2257f51 Revert "Revert "[cxx-interop] Import custom NS_OPTIONS correctly""
This reverts commit e1d70f06e7.
2023-09-15 13:57:59 +01:00
zoecarver
e1d70f06e7 Revert "[cxx-interop] Import custom NS_OPTIONS correctly"
This reverts commit 46f86f0870.
2023-09-11 11:46:43 -07:00
Egor Zhdan
e956e8ac1d [cxx-interop] Look up NSNotificationName in C++ language mode properly
This change makes sure that `NSNotification.Name.NEVPNStatusDidChange` is imported correctly when C++ interop is enabled.

`importer::findSwiftNewtype` is called while writing Clang modules, at a point when the translation-unit scope does not exist (`clangSema.TUScope` is `nullptr`).

That prevents the Clang lookup from discovering `NSNotificationName` declaration.

Instead of trying to pass a translation-unit scope to Clang, let's use qualified name lookup which does not require a scope.

rdar://112199372
2023-08-30 19:37:44 +01:00
Egor Zhdan
38820c19e8 [cxx-interop] NFC: Fix typo in test module name 2023-08-30 19:33:45 +01:00
Egor Zhdan
69727bb3de [cxx-interop] Add test for INADDR_ANY usage
At some point several months ago the `INADDR_ANY` macro from `Darwin.POSIX` module was not imported into Swift correctly. The issue seems to be resolved now. This change adds a test to make sure we don't regress again.

rdar://107429566
2023-08-22 16:51:02 +01:00
Egor Zhdan
46f86f0870 [cxx-interop] Import custom NS_OPTIONS correctly
This changes the heuristic that we use to detect `CF_OPTIONS`/`NS_OPTIONS` instantiations in C++ language mode.

Since libraries sometimes declare custom option types that break the assumptions about the names of such types, this lifts the requirements on the type name.

rdar://113524090
rdar://113279214
2023-08-18 15:41:50 +01:00
Egor Zhdan
4eb9c3be37 [cxx-interop] Make sure to create empty initializers for C++ structs
The existing synthesis mechanism had a bug: `cxxRecordDecl->hasDefaultConstructor()` returns true for C++ types with an implicit default constructor, for instance, `pthread_mutexattr_t`.

rdar://113708880
2023-08-14 17:46:57 +01:00
Egor Zhdan
6edde292f1 [cxx-interop] Import NSStreamDelegate.stream correctly
This Objective-C method
```
- (void)stream:(NSStream *)aStream
   handleEvent:(NSStreamEvent)eventCode;
```
should be imported as
```
optional func stream(
    _ aStream: Stream,
    handle eventCode: Stream.Event)
```
and not
```
optional func stream(
    _ aStream: Stream,
    handleEvent eventCode: Stream.Event)
```
in order to stay compatible with Objective-C interop mode.

rdar://113208675
2023-08-02 17:54:58 +01:00
Egor Zhdan
9edb752ac5 Merge pull request #67301 from apple/egorzhdan/foundation-linker-errors
[cxx-interop] Import CF_OPTIONS types such as `Foundation.NSTextCheckingType` correctly
2023-07-14 20:32:16 +01:00
Egor Zhdan
e6b830b640 [cxx-interop] Import CF_OPTIONS types such as Foundation.NSTextCheckingType correctly
This fixes linker errors which occurred when using Foundation extensions to `Swift.String`, such as `func replacingOccurrences`.

After the last rebranch, Clang started wrapping certain types in `clang::ElaboratedType`. This caused CF_OPTIONS types such as `Foundation.NSTextCheckingType` to be imported incorrectly in C++ language mode (`NSTextCheckingType` was imported as `uint64_t` without getting the special treatment of a CF type), which was causing deserialization errors when Swift tried reading `Foundation.swiftmodule`. Those deserialization errors were silenced by default. The IR for those functions was not emitted, which caused linker errors later.

rdar://109830032
2023-07-14 17:51:49 +01:00
Alex Lorenz
54c49db854 [cxx-interop] NFC, test, drop extern_c from a test module 2023-07-12 09:44:27 -07:00
Egor Zhdan
5a6203251c [cxx-interop] Import OS_OBJECT_DECL consistently with and without C++ interop enabled
Previously ClangImporter was not able to lookup `NSObject` when C++ interop is enabled, which caused types such as `xpc_object_t` from system module XPC to be imported differently: `any OS_xpc_object` without C++ interop vs `any NSObject & OS_xpc_object` with C++ interop enabled.

rdar://110000787
2023-07-04 21:32:17 +01:00
zoecarver
2114833e2e [nfc] Fix notification test 2023-06-23 12:05:11 -07:00
zoecarver
7964918cb2 [cxx-interop] Fix sema lookup scope so we find NSNotification interface even in C++ mode. 2023-06-22 12:21:10 -07:00
Alex Lorenz
4590aa1ede Merge pull request #65813 from hyp/eng/passInRegs
[cxx-interop] Itanium ABI C++ records should have address-only layout when they can't be passed in registers
2023-06-16 07:47:48 -07:00
Alex Lorenz
988f373055 [test] fix objcxx-arc-field-in-struct-type-layout-execution.swift test failure on macOS 2023-06-15 12:48:13 -07:00
Puyan Lotfi
fe6ccd7a29 [cxx-interop] Add fix for corner case where NS_OPTIONS typedef has to be desugared
This patch is an add-on to https://github.com/apple/swift/pull/64043.
Essentially when encountering NS_OPTIONS enums, in C++-Interop mode
if they are not specially handled then they can mangle differently than
they do without C++-Interop. This patch adds logic to handle when a
typedef and enum have additional clang::ElaboratedType sugar, but
otherwise it does the same as the existing 64043 patch.

The test case provided was encountered in a real app build. The problem
came from when two modules are each compiled one with and one without
C++-Interop. For the test case code provided the mangling of the
protocol conformance is not consistent and the code in
SILGenLazyConformance.cpp crashes on an invalid conformance with reason
"Invalid conformance in type-checked AST".
2023-06-15 11:17:25 -07:00
Alex Lorenz
49d7e041de [cxx-interop] C++ records should have address-only layout when they can't be passed in registers
This ensures that a C++ record with only ObjC ARC pointers with trivial other members is passed by value in SIL

Fixes https://github.com/apple/swift/issues/61929
2023-05-09 16:23:35 -07:00
Puyan Lotfi
6180387a05 [cxx-interop] Adding std.string initializer for UnsafePointer<CChar>?
Currently without an initializer for the unsafe char pointer type swiftc
hits an assert around not being able to handle conversions of unsafe
pointers with Any type. This patch adds the ability to convert to a
std::string.

This is to address issue https://github.com/apple/swift/issues/61218
2023-04-12 22:03:57 -04:00
Alex Lorenz
9feb76419b [interop] ignore exceptions in existing interop tests 2023-02-22 11:00:51 -08:00
Puyan Lotfi
4f2f348356 [C++-Interop] Allow for calling automatically synthesized ctors of arc types
When instantiating C++ types who contain ARC types in the past either
their default constructors are skipped or they are synthesized with
Unmanged<> wrappers. This has made it more cumbersome to instantiate
these from Swift and often requires a static C++ build method to
manually shim the synthesized constructor. The following change drops
the Unmanaged<> so that for the time being these types can be
instantiated directly even if types like Swift -> NSString are not
bridged completely.

(cherry picked from commit accdace5f0438860a0d6760d9598402a9998a324)
(cherry picked from commit 567763c9ec76e14b0d6af5707e50b1674b2c2cbf)
2023-02-15 18:01:04 -05:00
Daniel Rodríguez Troitiño
691dcc9bb3 Test case for const T& in Obj-C++ methods
Add a test case that checks the behaviour introduced during the refactor
of `importFunctionParameterList` and `importMethodParamsAndReturnType`.

The test checks that both Obj-C++ methods and C++ functions treat `const
T&` parameters in the same way.
2022-09-02 11:51:15 -07:00