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
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
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]].
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.
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.
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
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
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
* 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.
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.
The std::basic_string class is escapable only if its template argument
is escapable. This change helps us consider the regular std::string type
with the non-escapable char template argument as self-contained and a
safe type to use. This prevents spurious warnings in strict memory
safety mode.
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.
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
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.
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
When Swift passes search paths to clang, it does so directly into the HeaderSearch. That means that those paths get ordered inconsistently compared to the equivalent clang flag, and causes inconsistencies when building clang modules with clang and with Swift. Instead of touching the HeaderSearch directly, pass Swift search paths as driver flags, just do them after the -Xcc ones.
Swift doesn't have a way to pass a search path to clang as -isystem, only as -I which usually isn't the right flag. Add an -Isystem Swift flag so that those paths can be passed to clang as -isystem.
rdar://93951328
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.
* 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
`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.
Nested calls to importBaseMemberDecl() subvert its cache and compromise its idempotence, causing the semantic checker to spuriously report ambiguous member lookups when multiple ClangRecordMemberLookup requests are made (e.g., because of an unrelated missing member lookup).
One such scenario is documented as a test case: test/Interop/Cxx/class/inheritance/inherited-lookup-typechecker.swift fails without this patch because of the expected error from the missing member. Meanwhile, test/Interop/Cxx/class/inheritance/inherited-lookup-executable.swift works because it does not attempt to access a missing member.
This patch fixes the issue by only calling importBaseMemberDecl() in the most derived class (where the ClangRecordMemberLookup originated, i.e., not in recursive requests).
As a consequence of my patch, synthesized member accessors in the derived class directly invoke the member from the base class where the member is inherited from, rather than incurring an indirection at each level of inheritance. As such, the synthesized symbol names are different (and shorter). I've taken this opportunity to update the relevant tests to // CHECK for more of the mangled symbol, rather than only the synthesized symbol prefix, for more precise testing and slightly better readability.
rdar://141069984
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.
When cloning the clang instance in ClangImporter to perform tasks like
PCM/PCH compilation, make two compiler instance to share the same
CASOptions so they can share the CAS ObjectStore and life time.
This fixes a case where clang emits a diagnostics in a source buffer that
gets mapped in via CAS, and mapped into swift source manager. While CAS has
the ownship from CompilerInvocation -> CASOptions -> CAS, if the
CompilerInvocation is deleted when the cloned instance is deleted, it
left an invalid buffer in the swift source manager.
rdar://141284501
This results in an automatic wrapper function with safe pointer types
when the imported function has bounds attributes. This exercises similar
pathways as the recently added functionality for specifying macros from
swift_attr. The new functionality is guarded by the experimental
language feature SafeInteropWrappers.
rdar://97942270