Commit Graph

617 Commits

Author SHA1 Message Date
John Hui
ce680eae55 [cxx-interop] Add test case that checks irgen for imported private members (#80515) 2025-04-09 11:05:43 -07:00
Gabor Horvath
e0a431ec98 [cxx-interop] Diagnose Escapable C++ types with non-escapable fields
rdar://148899224
2025-04-09 13:01:31 +01:00
fahadnayyar
5d1ce01eb9 [cxx-interop] Import parameterized public ctors of C++ foreign ref types as Swift Initializer (#80449)
Extends PR #79986 by adding support for calling parameterized C++ initializers from Swift. This patch synthesizes static factory methods corresponding to C++ parameterized constructors, allowing Swift to call them as Swift initializers (e.g., init(_:), init(_:_:), etc.). This patch also aded tests and logic to make sure that we emit no additional diagnostics when a C++ foreign ref type is just referred from Swift and its initializer is not explicitly called.

rdar://148285251
2025-04-08 08:58:11 -07:00
Crazy凡
c05d1fc135 [c++ interop] Swift should allow multiple SWIFT_CONFORMS_TO_PROTOCOL attributes on a C++ class. 2025-04-06 22:24:14 +08:00
John Hui
e8bcc52356 [cxx-interop] Fix access check for nested private C++ enums (#80366)
This patch fixes the access check for nested private C++ enums to look for the SWIFT_PRIVATE_FILEID of the enclosing C++ class, if any. Previously, the check was looking at for SWIFT_PRIVATE_FILEID on the enum decl itself (which is meaningless); that prevented nested private enum members from being accessible in Swift.

This patch also specializes the type signature of getPrivateFileIDAttrs to clarify the fact that SWIFT_PRIVATE_FILEID is not a meaningful annotation on anything other than CXXRecordDecl, because that is the only kind of decl that can assign access specifiers to its members.

rdar://148081340
2025-03-31 22:23:22 -07:00
fahadnayyar
9694cc8d70 [cxx-interop] Import default public ctor of C++ foreign ref types as Swift Initializer (#79986)
Building on top of PR #79288, this update synthesizes a static factory method using the default new operator, with a call to the default constructor expression for C++ foreign reference types, and imports them as Swift initializers.

rdar://147529406
2025-03-31 20:33:53 -07:00
John Hui
bbf92fd6e1 [cxx-interop] Import non-public members of SWIFT_PRIVATE_FILEID-annotated classes (#80320) 2025-03-26 22:41:38 -07:00
Gabor Horvath
ff42f2ee79 [cxx-interop] Fix a regression making std::string unsafe
Currently, we only get warnings for using unsafe types in expressions
but not in the function signature. The tests did not use the std::string
object in the function body. As a result, we regressed and std::string
was considered unsafe.

The reason is that the annotation only mode for calculating escapability
of a type did not do what we intended. std::basic_string is
conditionally escapable if the template argument is escapable. We
considered 'char' to have unknown escapability in annotation only mode.
The annotation only mode was introduced to avoid suddenly importing
certain types as not escapable when they have pointer fields and break
backward compatibility.

The solution is to make annotation only mode to still consider char and
co as escapable types and only fall back to unknown when the inference
otherwise would have deduced non-escapable (for unannotated typed).
2025-03-26 15:25:37 +00:00
Gábor Horváth
b0ffa78e27 Merge pull request #80267 from swiftlang/gaborh/unbreak-ci-irgen
[cxx-interop] Unbreak CI
2025-03-25 16:24:03 +00:00
Gabor Horvath
bad91d6260 [cxx-interop] Unbreak CI
Make the test more resilient to variations in the IR to match what is
generated on one of the CI machines.

rdar://147091383
2025-03-25 11:39:09 +00:00
Gábor Horváth
16cefca106 Merge pull request #80197 from swiftlang/gaborh/mutating-class-func
[cxx-interop] Do not create mutating properties for classes
2025-03-24 14:17:36 +00:00
Gabor Horvath
51193fa538 [cxx-interop] Do not create mutating properties for classes
In Swift, only value types can have mutating instance member functions
or computed properties. The importer logic was violating this invariant
when generating setters for bit fields of shared references.

Fixes #80182
2025-03-21 19:02:35 +00:00
Guillaume Lessard
d66fde2e47 [test] fix availability 2025-03-20 13:03:54 -07:00
Susana Monteiro
a8111e4786 Merge pull request #80094 from swiftlang/susmonteiro/destructor-missing-dbg-info
[cxx-interop] Disable debug info in synthesized C++ methods
2025-03-20 10:26:56 +00:00
Andrew Trick
8432d2e788 Fix C++ interop tests using swift_attr("~Escapable")) 2025-03-19 11:59:05 -07:00
Andrew Trick
64a48d08e1 Update tests for strict @lifetime type checking 2025-03-19 11:59:04 -07:00
susmonteiro
25efb5fc04 [cxx-interop] Disable debug info in synthesized C++ methods
rdar://141167229
2025-03-19 18:02:50 +00:00
Florian Hahn
dff5da4b32 [Test] Use -disable-llvm-merge-function-pass to unblock MergeFunc fix.
To unblock CI for https://github.com/swiftlang/llvm-project/pull/10112.
2025-03-14 09:49:14 +00:00
Gabor Horvath
14d92ff7a1 [cxx-interop] Test static factory backed initializers with value types
We can use swift_name to import a static factory function as a Swift
initializer. This was tested with foreign reference types but not with
value types. This PR adds a test case for the latter.

rdar://117531428
2025-03-11 17:36:54 +00:00
Gábor Horváth
94ca6fa86a Merge pull request #79793 from swiftlang/gaborh/remove-feature-flag 2025-03-10 17:57:26 +01:00
susmonteiro
51357a952c [cxx-interop] Prevent usage in Swift of C++ move constructor with default args 2025-03-07 16:02:38 +00:00
Gabor Horvath
6b24af65f0 [cxx-interop] Always import the lifetime annotations
Importing these annotations were behind the LifetimeDependence
experimental flag. However, this feature flag is intended to guard the
use of @lifetime annotations on the Swift side and lifetime inference.
The checking of imported lifetime contracts should work even when this
flag is off. Removing the flag from the importer caused some fallout.
This was mostly due to calling getInterfaceType functions before the
import of some Swift declarations were fully done so the code was
slightly improved to make decisions only based on the C++ types.
There was also a crash when on-member functions imported as methods into
Swift. That is worked around in this PR.

There is one last feature check that we cannot remove yet, we generate
@lifetime annotations in the SwiftifyImport macro.
2025-03-05 15:36:59 +00:00
John Hui
edc742013d [cxx-interop] Make experimental flag ImportNonPublicCxxMembers (#79728)
ClangImporter can now import non-public members as of be73254cdc and 66c2e2c52b, but doing so triggers some latent ClangImporter bugs in projects that don't use or need those non-public members.

This patch introduces a new experimental feature flag, ImportNonPublicCxxMembers, that guards against the importation of non-public members while we iron out those latent issues. Adopters of the SWIFT_PRIVATE_FILEID feature introduced in bdf22948ce can enable this flag to opt into importing private members they wish to access from Swift.

rdar://145569473
2025-03-04 13:31:46 -05:00
Gábor Horváth
3b412ae0c6 Merge pull request #79697 from swiftlang/gaborh/do-not-import-nonesc-pointees
[cxx-importer] Do not import pointers to non-escapable types
2025-03-04 17:26:38 +00:00
Susana Monteiro
593f320460 Merge pull request #79325 from swiftlang/susmonteiro/copy-constructor-default-args
[cxx-interop] Prevent usage in Swift of C++ copy constructor with default args
2025-03-04 15:40:22 +00:00
Gabor Horvath
d0c167762c [cxx-importer] Do not import pointers to non-escapable types
Unfortunately, Unsafe*Pointer types do not support non-escapable
pointees so we do not really have anything to map these types to at the
moment. Previously, importing such code resulted in crashes.

rdar://145800679
2025-03-04 12:27:34 +00:00
susmonteiro
bc6573ec32 [cxx-interop] Prevent usage in Swift of C++ copy constructor with default args 2025-03-03 13:22:11 +00:00
Doug Gregor
b7b5a2a19d [SE-0458] Enable unsafe expressions / attributes / for..in effects by default
With the acceptance of SE-0458, allow the use of unsafe expressions, the
@safe and @unsafe attributes, and the `unsafe` effect on the for..in loop
in all Swift code.

Introduce the `-strict-memory-safety` flag detailed in the proposal to
enable strict memory safety checking. This enables a new class of
feature, an optional feature (that is *not* upcoming or experimental),
and which can be detected via `hasFeature(StrictMemorySafety)`.
2025-02-26 12:30:07 -08:00
John Hui
66c2e2c52b [cxx-interop] Import non-public inherited members (#79348)
This patch is follow-up work from #78942 and imports non-public members,
which were previously not being imported. Those members can be accessed
in a Swift file blessed by the SWIFT_PRIVATE_FILEID annotation.

As a consequence of this patch, we are also now importing inherited members
that are inaccessible from the derived classes, because they were declared
private, or because they were inherited via nested private inheritance. We
import them anyway but mark them unavailable, for better diagnostics and to
(somewhat) simplify the import logic for inheritance.

Because non-public base class members are now imported too, this patch
inflames an existing issue where a 'using' declaration on an inherited member
with a synthesized name (e.g., operators) produces duplicate members, leading
to miscompilation (resulting in a runtime crash). This was not previously noticed
because a 'using' declaration on a public inherited member is not usually
necessary, but is a common way to expose otherwise non-public members.
This patch puts in a workaround to prevent this from affecting the behavior
of MSVC's std::optional implementation, which uses this pattern of 'using'
a private inherited member. That will be fixed in a follow-up patch.

Follow-up work is also needed to correctly diagnose ambiguous overloads
in cases of multiple inheritance, and to account for virtual inheritance.

rdar://137764620
2025-02-25 01:03:16 -08:00
fahadnayyar
9782eae585 Merge pull request #77522 from fahadnayyar/cxx-frt-inheritance-diagnostics
[cxx-interop] Infer SWIFT_SHARED_REFERENCE for types inheriting from a C++ foreign reference type
2025-02-20 13:46:28 -08:00
fahadnayyar
d8f919778d [cxx-interop] [cxx-interop] Infer SWIFT_SHARED_REFERENCE for types inheriting from a C++ foreign reference type
rdar://97914474
2025-02-20 08:46:57 -08:00
Gábor Horváth
91531554de Merge pull request #79458 from swiftlang/gaborh/unsafe-cleanup 2025-02-18 20:33:08 +00:00
John Hui
bdf22948ce [cxx-interop] Allow Swift to access non-public C++ members (#79093)
This patch introduces an a C++ class annotation, SWIFT_PRIVATE_FILEID,
which will specify where Swift extensions of that class will be allowed
to access its non-public members, e.g.:

    class SWIFT_PRIVATE_FILEID("MyModule/MyFile.swift") Foo { ... };

The goal of this feature is to help C++ developers incrementally migrate
the implementation of their C++ classes to Swift, without breaking
encapsulation and indiscriminately exposing those classes' private and
protected fields.

As an implementation detail of this feature, this patch introduces an
abstraction for file ID strings, FileIDStr, which represent a parsed pair
of module name/file name.

rdar://137764620
2025-02-18 11:22:44 -08:00
Gabor Horvath
c859557f8b [cxx-interop] Remove duplicated logic to import types as unsafe
After PR #79424 was merged the compiler proper is doing inference on
what C++ types should be considered unsafe. Remove the duplicated (and
slightly divergent) logic from the importer as we no longer need it and
we should have a consistent view of what is considered unsafe. The only
divergence left is the old logic that renames some methods to have
"Unsafe" in their names. In the future, we want to get rid of this
behavior (potentially under a new interop version).
2025-02-18 12:22:40 +00:00
Gabor Horvath
648fd43709 [cxx-interop] Remove a feature flag
SafeInterop was guarding whether we import certain foreign types as
unsafe. Since these attrbutes are only considered when an opt-in strict
language mode is on, this PR removes this feature flag. We still rely on
the presence of the AllowUnsafeAttribute flag to add the unsafe
attributes to the imported types and functions.
2025-02-17 12:37:31 +00:00
Doug Gregor
c0fb9f990a [Strict memory safety] Infer safe/unsafe for imported C types 2025-02-16 00:55:43 -08:00
Gabor Horvath
e79e04c0a6 [cxx-interop] Mark C++ reference parameters @addressable
C++ code can return values that depend on the storage that backs the
references that were passed in as argument. Thus, swift should not
introdue temporary copies of that storage before invoking those
functions as they could result in lifetime issues.
2025-02-11 11:10:51 +00:00
Gábor Horváth
40deafb285 Merge pull request #79076 from swiftlang/gaborh/zero-sized-field-import
[cxx-interop] Do not codegen zero-sized fields
2025-02-03 17:22:00 +00:00
Gabor Horvath
998591e9f9 [cxx-interop] Do not import zero-sized fields
Zero sized fields are messing up the offset calculations when we import
C++ fields to Swift. We assume that the size of the field is determined
by the type of the field. This is not true for fields marked with
no_unique_address. Those fields can have 0 size while the
sizeof(decltype(field)) is still 1.

rdar://143907490
2025-02-03 11:55:54 +00:00
John Hui
be73254cdc [cxx-interop] Import private members (#78942)
This commit removes the guardrails in ImportDecl.cpp:SwiftDeclConverter
that prevent it from importing non-public C++ members. It also
accordingly adjusts all code that assumes generated Swift decls should
be public. This commit does not import non-public inherited members;
that needs its own follow-up patch.

Note that Swift enforces stricter invariants about access levels than C++.
For instance, public typealiases cannot be assigned private underlying types,
and public functions cannot take or return private types. Meanwhile,
both of these patterns are supported in C++, where exposing private types
from a class's public interface is considered feature. As far as I am aware,
Swift was already importing such private-containing public decls from C++
already, but I added a test suite, access inversion, that checks and
documents this scenario, to ensure that it doesn't trip any assertions.
2025-01-30 14:50:15 -08:00
Gábor Horváth
109e2081b6 Merge pull request #78807 from swiftlang/gaborh/generated-ctors
[cxx-interop] Fix spurious lifetime dependence errors
2025-01-29 17:59:03 +00:00
Gabor Horvath
dd3db51f60 [cxx-interop] Make borrowing specifiers more precise
We do not need to borrow from view objects passed by value but we need
to borrow from owners taken by const reference regardless of whether it
was annotated using lifetimebound or lifetime_capture_by.
2025-01-29 11:49:32 +00:00
Doug Gregor
b3f2f00588 Suggest both @unsafe and @safe Fix-Its for unsafe types in signature 2025-01-23 07:47:19 -08:00
Gábor Horváth
795d62987f Merge pull request #78771 from swiftlang/gaborh/unsafe-lifetime-unannotated
[cxx-interop] Require lifetime annotations in safe mode
2025-01-22 18:45:26 +00:00
Gabor Horvath
b6fce85287 [cxx-interop] Fix spurious lifetime dependence errors
ClangImporter will generate value and default initializers for certain
structs imported from C++. These generated initializers have no
associated lifetime dependence information so they will trigger spurious
errors for non-escapable types. This patch makes sure these are marked
as unsafe so the type checker will not generate errors for them.
Moreover, the generated default initializer would trigger a crash for
non-escapable types as the builtin to zero initialize an object does not
support non-escapable types yet.

rdar://143040862
2025-01-22 15:34:02 +00:00
John Hui
1341516dba [cxx-interop] Fix spurious ambiguous member lookup for eagerly imported members (#78673)
Follow-up from #78132, which did not fix issues related to eagerly imported members like subscripts.

This patch restructures recursive ClangRecordMemberLookup requests to importBaseMemberDecl() in the recursive calls, rather than propagating base member decls up to the initial lookup request and doing the import. Doing so seems to fix lingering resolution issues (which I've added to the regression tests).

rdar://141069984
2025-01-21 22:06:09 -08:00
Gabor Horvath
0a38617e39 [cxx-interop] Require lifetime annotations in safe mode
In strict safe mode we should consider all C++ APIs with non-escapable
parameters unsafe unless they have their lifetimes annotated. This can
be done using [[clang::lifetimebound]], [[clang::lifetime_capture_by]],
or [[clang::noescape]].
2025-01-21 12:54:21 +00:00
Gabor Horvath
f12b48aa86 [cxx-interop] Check the safety of C++ template arguments
Swift imports template specializations as a standalone type (not as an
instantiation of a generic) so unsafety is not propagated from the
template arguments to the specialization. This PR propagates this
information explicitly.
2025-01-17 17:39:25 +00:00
Gábor Horváth
4ae5685536 Merge pull request #78544 from swiftlang/gaborh/calling-conv
[cxx-interop] Fix wrong calling convention for some C++ types
2025-01-14 10:12:29 +00:00
Egor Zhdan
18be5e862d Merge pull request #78467 from swiftlang/egorzhdan/sizeof-incomplete
[cxx-interop] Skip type metadata for C++ types that are only used in private C++ fields
2025-01-13 16:58:08 +00:00