Commit Graph

2550 Commits

Author SHA1 Message Date
Joe Groff
f778170cfb Merge pull request #79351 from jckarter/lifetime-dependence-lowering
SIL: Lower lifetime dependencies when lowering function types.
2025-02-17 07:51:20 -08:00
Gabor Horvath
410341671e [SE-0458] Unify escapibility inference for AST and Interop
Interop is injecting escapability annotations for the STL and doing a
limited inference for aggregates. Let's reuse the same facilities in the
AST when we calculate the safety of the foreign types.
2025-02-17 13:41: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
Hamish Knight
1e8dc55b7f [AST] NFC: Remove InitRetType
This is no longer used.
2025-02-16 18:52:23 +00:00
Joe Groff
c65475628f SIL: Lower lifetime dependencies when lowering function types.
Map the lifetime dependencies described in terms of the formal AST-level parameters
to the correct parameter(s) in the lowered SIL function type. There can be 0, 1,
or many SIL parameters per formal parameter because of tuple exploding. Also,
record which dependencies are on addressable parameters (meaning that the dependency
includes not only the value of the parameter, but its specific memory location).
2025-02-14 09:47:53 -08:00
Gabor Horvath
068815c2a3 [cxx-interop] Remove some duplicated lookups
Repeatedly lookup up a key from a dictionary can be justified whenever
the content of the dictionary might change between the lookups (so any
references into the dictionary might get invalidated). We had a couple
of instances where as far as I can tell no such modifications should
happen between two lookups with identical keys. This PR simplifies the
code to remove the extra lookups. It also removes a dictionary that was
completely unused.
2025-02-14 11:04:23 +00:00
Becca Royal-Gordon
2b2252b6a6 Gracefully handle incorrect SwiftName arg count
…at least in the specific case of initializers.

Normally, clang validates that a SwiftNameAttr’s specified name seems to have the right number of argument labels for the declaration it’s applied to; if it doesn’t, it diagnoses and drops the attribute. However, this checking isn’t perfect because clang doesn’t know all of Clang Importer’s throwing rules. The upshot is that it’s possible to get a mismatched SwiftNameAttr into Clang Importer if the last parameter looks like an out parameter. This trips an assertion in asserts compilers, but release compilers get past that and don’t seem to notice the mismatch at all.

Add code to the compiler to tolerate this condition, at least in initializers, by modifying the Swift name to have the correct number of argument labels and deprecating the declaration with a message explaining the problem.

Fixes rdar://141124373.
2025-02-11 17:37:25 -08:00
Becca Royal-Gordon
12d0458eb2 Diagnose and forbid invalid Swift names on inits
Initializers should always have Swift names that have the special `DeclBaseName::createConstructor()` base name. Although there is an assertion to this effect in the constructor for ConstructorDecl, ClangImporter did not actually reject custom Swift names for initializers that violated this rule. This meant that asserts compilers would crash if they encountered code with an invalid `swift_name` attribute, while release compilers would silently accept them (while excluding these decls from certain checks since lookups that were supposed to find all initializers didn’t find them).

Modify ClangImporter to diagnose this condition and ignore the custom Swift name.
2025-02-11 12:05:17 -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
Anthony Latsis
34f9b80cbc Merge pull request #78750 from AnthonyLatsis/oryza-sativa
[Gardening] Fix some set but not used variables
2025-01-31 04:29:05 +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
Anthony Latsis
a84dfc8387 [Gardening] Fix some set but not used variables 2025-01-30 21:34:38 +00: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
Gábor Horváth
8462105e29 Merge pull request #78947 from swiftlang/gaborh/lifetimebound-this 2025-01-29 09:09:53 +00:00
Gabor Horvath
06e5ead8da [cxx-interop] Support borrowing from self in SwiftifyImport
Support adding safe wrappers for APIs returning std::span depending on
the this object. This also fixes an issue for APIs with 0 parameters.

rdar://139074571
2025-01-28 13:54:10 +00:00
Gábor Horváth
6a3011d8e5 Merge pull request #78882 from swiftlang/gaborh/missing-break 2025-01-28 11:20:37 +00:00
Egor Zhdan
7c7f9fd956 Merge pull request #78852 from swiftlang/egorzhdan/revert-simd
Revert "[cxx-interop] Workaround name lookup issues with namespace simd"
2025-01-28 10:57:03 +00:00
Henrik G. Olsson
fdea6ba8d0 [Swiftify][ClangImporter] Import noescape attribute for parameters (#78713)
This passes along the noescape attribute to @_SwiftifyImport as
.noescape(pointer: .param(X)). This allows importing parameters as Span,
MutableSpan and RawSpan.
2025-01-27 10:01:06 -08:00
Allan Shortlidge
7b8cbd7109 AST: Store unresolved domain strings in AvailableAttr.
This is the first step towards resolving the AvailabilityDomain associated with
an AvailableAttr during type checking instead of parsing.
2025-01-26 13:50:56 -08:00
Gabor Horvath
303aa1b791 [cxx-interop] Avoid creating duplicate unsafe attributes 2025-01-24 12:46:07 +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
Gábor Horváth
91d7cc445a Merge pull request #78761 from swiftlang/gaborh/span-lifetimebound-end-to-end
[cxx-interop] Make ClangImporter support lifetimebound annotated spans
2025-01-22 19:04:34 +00: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
Gabor Horvath
042b108e6f [cxx-interop] Make ClangImporter support lifetimebound annotated spans
Generate safe Swift Span wrappers using the new SwiftifyImport macro.

rdar://139074571
2025-01-22 15:07:02 +00:00
Becca Royal-Gordon
ebea19d7b9 Merge pull request #78697 from beccadax/rdar142693093
Work around Foundation NS_TYPED_ENUM bug
2025-01-22 00:57:41 -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
Gábor Horváth
3bbb126e4c Merge pull request #78522 from swiftlang/gaborh/instantiation-unsafe
[cxx-interop] Check the safety of C++ template arguments
2025-01-20 16:59:56 +00:00
Becca Royal-Gordon
56b20351e3 Work around Foundation NS_TYPED_ENUM bug
Consider code like:

```
// Foo.h
typealias NSString * FooKey NS_EXTENSIBLE_TYPED_ENUM;

// Foo.swift
extension FooKey { … }
```

When Swift binds the extension to `FooKey`, that forces ClangImporter to import `FooKey`. ClangImporter’s newtype logic, among other things, checks whether the underlying type (`Swift.String` here) is Objective-C bridgeable and, if so, makes `FooKey` bridgeable too.

But what happens if this code is actually *in* Foundation, which is where the `extension String: _ObjectiveCBridgeable` lives? Well, if the compiler has already bound that extension, it works fine…but if it hasn’t, `FooKey` ends up unbridgeable, which can cause both type checking failures and IRGen crashes when code tries to use its bridging capabilities. And these symptoms are sensitive to precise details of the order Swift happens to bind extensions in, so e.g. adding empty files to the project can make the bug appear or disappear. Spooky.

Add a narrow hack to ClangImporter (only active for types in Foundation) to *assume* that `String` is bridgeable even if the extension declaring this hasn’t been bound yet.

Fixes rdar://142693093.
2025-01-17 17:22:55 -08: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
Egor Zhdan
cb2bd321ce [cxx-interop] Do not import std::__compressed_pair
This type is triggering modularization issues in libc++:
```
error: definition of '__builtin_new_deleter' must be imported from module 'std_private_memory_builtin_new_allocator' before it is required
```

This is a workaround to keep things building.

rdar://142576799
2025-01-16 23:41:29 +00: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
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
Henrik G. Olsson
d7bd76e9f1 [Swiftify] Add return pointer support (#78571)
* Import __counted_by for function return values

Instead of simply passing a parameter index to _SwiftifyInfo, the
_SwiftifyExpr enum is introduced. It currently has two cases:
 - .param(index: Int), corresponding to the previous parameter index
 - .return, corresponding to the function's return value.

ClangImporter is also updated to pass this new information along to
_SwiftifyImport, allowing overloads with buffer pointer return types to
be generated. The swiftified return values currently return Span when
the return value is marked as nonescaping, despite this not being sound.
This is a bug that will be fixed in the next commit, as the issue is
greater than just for return values.

* Fix Span variant selection

There was an assumption that all converted pointers were either
converted to Span-family pointers, or UnsafeBufferPointer-family
pointers. This was not consistently handled, resulting in violating the
`assert(nonescaping)` assert when the two were mixed. This patch removes
the Variant struct, and instead each swiftified pointer separately
tracks whether it should map to Span or UnsafeBufferPointer.
This also fixes return pointers being incorrectly mapped to Span when
marked as nonescaping.
2025-01-13 08:08:36 -08:00
Ellie Shin
727fb8c32d Merge pull request #78258 from swiftlang/elsh/disallow-bypass-deser-check
Package CMO: add deserialization checks to ensure correct memory layout
2025-01-11 05:40:49 -08:00
Allan Shortlidge
7b4af34f40 ClangImporter: Adopt new AvailableAttr constructor. 2025-01-10 18:43:12 -08:00
Allan Shortlidge
86ea1ae775 AST: Introduce a Kind enum and new constructor for AvailableAttr.
AvailableAttr::Kind and AvailabilityDomain are designed to replace
PlatformAgnosticAvailabilityKind, allowing AvailableAttr to more flexibly model
availability for arbitrary domains. For now, the new constructor just
translates its inputs into inputs for the existing constructor. Once all of the
callers of the existing AvailableAttr constructor have been updated to use the
new constructor, the representation of AvailableAttr will be updated to store
the new properties.
2025-01-10 18:43:12 -08:00
Allan Shortlidge
635ea34bb5 Merge pull request #78503 from tshortli/available-attr-creation-conveniences
AST: Introduce new conveniences for synthesizing AvailabilityAttrs
2025-01-09 08:21:40 -08:00
Gábor Horváth
b31b90d862 Merge pull request #78422 from swiftlang/gaborh/cxx-span-overload-importer
[cxx-interop] Generate safe overloads for non-escapable spans
2025-01-09 12:10:30 +00:00
Allan Shortlidge
70a2363b97 AST: Introduce new conveniences for synthesizing AvailabilityAttrs.
This makes intent clearer at the call site and removes a lot of explicit uses
of PlatformAgnosticAvailabilityKind, which is going away.
2025-01-08 19:59:47 -08:00
Fahad Nayyar
69332f706f [cxx-interop] Diagnose ObjC APIs returning SWIFT_SHARED_REFERENCE types
rdar://142500663
2025-01-08 11:36:49 -08:00
Gabor Horvath
4846c56795 [cxx-interop] Generate safe overloads for non-escapable spans
A previous PR already added support to the SwiftifyImport macro to
generate safe wrappers. This PR makes ClangImporter emit the macro to do
the transformation.
2025-01-08 11:19:35 +00:00
elsh
c03abed00d Package optimization allows bypassing resilience, but that assumes the memory layout of the
decl being accessed is correct. When this assumption fails due to a deserialization error
of its members, the use site accesses the layout with a wrong field offset, resulting in
UB or a crash. The deserialization error is currently not caught at compile time due to
LangOpts.EnableDeserializationRecovery being enabled by default to allow for recovery of some
of the deserialization errors at a later time. In case of member deserialization, however,
it's not necessarily recovered later on.

This PR tracks whether member deserialization had an error by recursively loading members and
checking for deserialization error, and fails and emits a diagnostic. It provides a way to
prevent resilience bypassing when the deserialized decl's layout is incorrect.

Resolves rdar://132411524
2025-01-07 21:51:49 -08:00
Allan Shortlidge
d0f63a0753 AST: Split Availability.h into multiple headers.
Put AvailabilityRange into its own header with very few dependencies so that it
can be included freely in other headers that need to use it as a complete type.

NFC.
2025-01-03 18:36:04 -08:00
Doug Gregor
5b90b8851a Generalize protocol conformance options spelled via attribute and incorporate @unsafe
Protocol conformances have a handful attributes that can apply to them
directly, including @unchecked (for Sendable), @preconcurrency, and
@retroactive. Generalize this into an option set that we carry around,
so it's a bit easier to add them, as well as reworking the
serialization logic to deal with an arbitrary number of such options.

Use this generality to add support for @unsafe conformances, which are
needed when unsafe witnesses are used to conform to safe requirements.
Implement general support for @unsafe conformances, including
producing a single diagnostic per missing @unsafe that provides a
Fix-It and collects together all of the unsafe witnesses as notes.
2024-12-20 23:16:23 -08:00
Henrik G. Olsson
ef9d2b744d Rename pointer bounds (#78210)
* Make pointer bounds non-experimental

* Rename @PointerBounds to @_SwiftifyImport

* Rename filenames containing PointerBounds

* Add _PointerParam exception to stdlib ABI test

* Add _PointerParam to stdlib API changes

* Rename _PointerParam to _SwiftifyInfo
2024-12-20 11:36:01 +01:00
Allan Shortlidge
94e678da37 ClangImporter: Ignore missing imports in SwiftDeclConverter::recordObjCOverride().
`recordObjCOverride()` records semantic overrides for imported Obj-C methods.
Since these methods are imported from a different language, it doesn't make
sense to enforce Swift's member import visibility rules when performing lookups
to find overridden methods. Doing so caused the Constrain Solver to lack
important information needed to eliminate overloads, resulting in erroneous
ambiguities.

Resolves rdar://141636723.
2024-12-18 08:34:44 -08:00
Gábor Horváth
568fa14b14 Merge pull request #77617 from swiftlang/gaborh/support-lifetime-capture-by
[cxx-interop] Support lifetime_capture_by in ClangImporter
2024-12-18 13:53:16 +00:00
Gabor Horvath
8399971f06 [cxx-interop] Support lifetime_capture_by in ClangImporter
Import it as lifetime dependencies.

rdar://137671377
2024-12-18 10:05:43 +00:00
Gabor Horvath
985c3a44f8 [cxx-interop] Make sure C++ span is imported as @unsafe
The C++ span should be a non-escapable type but is imported as escapable
for backward compatibility reason. This is inherently unsafe, so make
sure std::span is imported as such. In the future, we plan to generate
safe overloads using Swift's Span and that will be the preferred way of
using the API.
2024-12-16 17:11:22 +00:00