This patch re-enables diagnostics for unannotated C++ functions or
methods returning `SWIFT_SHARED_REFERENCE` types. These warnings now
fire only **once per source location**, even in the presence of multiple
template instantiations. This avoids diagnostic duplication that was a
key source of noise in the compilation of larger codebases.
These warnings were previously disabled starting in **Swift 6.2** via
[PR-#81411](https://github.com/swiftlang/swift/pull/81411) due to
concerns around false positives and excessive duplication in projects
adopting C++ interop. This patch addresses the duplication issue by
adding source-location-based caching, which ensures that a warning is
emitted only once per source location, even across template
instantiations with different types.
However, the false positive issue remains to be investigated and will be
addressed in a follow-up patch. Until that happens, the warnings are
gated behind a new experimental feature flag:
`WarnUnannotatedReturnOfCxxFrt`. This feature will be enabled by default
only after thorough qualification and testing on large C++ codebases.
rdar://154261051
When importing custom availability domains with dynamic predicates from Clang
modules, synthesize predicate functions for `if #available` queries and call
them when generating SIL.
Resolves rdar://138441312.
When MemberImportVisibility is enabled we failed to find certain base
methods from the extensions when said base methods are imported from
C++.
rdar://154887575
Initially, the compiler rejected building dependencies that contained OS
versions in an invalid range. However, this happens to be quite
disruptive, so instead allow it and request that these versions be
implicitly bumped based on what `llvm::Triple::getCanonicalVersionForOS`
computes.
resolves: rdar://153205856
This patch makes sure we don't get warnings in strict memory safe mode
when using shared references. Those types are reference counted so we
are unlikely to run into lifetime errors.
rdar://151039766
When building against the static standard library, we should define
`SWIFT_STATIC_STDLIB` to indicate to the shims that the declarations
should be giving hidden visibility and default DLL storage. This is
required to ensure that these symbols are known to be `dso_local` when
compiling to avoid an unnecessary look up through the PLT/GOT or the
indirection through the synthesized `__imp_` symbol and the IAT. This
corrects a number of incorrect code generation cases on Windows with the
static standard library.
Create a path that swift-frontend can execute an uncached job from
modules built with CAS based explicit module build. The new flag
-import-module-from-cas will allow an uncached build to load module
from CAS, and combined with source file from real file system to build
the current module. This allows quick iterations that bypasses CAS,
without full dependency scanning every time in between.
rdar://152441866
When the compiler is building a module without a defined formal C++ interop mode (e.g. building a textual interface which specifies it was built without C++ interop enabled), avoid looking up the C++ standard library Swift overlay for it. This is required for the case of the Darwin module, for example, which includes headers which map to C++ stdlib headers when the compiler is operating in C++ interop mode, but the C++ standard library Swift overlay module itself depends on 'Darwin', which results in a cycle. To resolve such situations, we can rely on the fact that Swift textual interfaces of modules which were not built with C++ interop must be able to build without importing the C++ standard library Swift overlay, so we avoid specifying it as a dependency for such modules. The primary source module, as well as Swift textual module dependencies which were built with C++ interop will continue getting a direct depedency of the 'CxxStdlib' Swift module.
This was previously fixed in the dependency scanner for explicitly-built modules in https://github.com/swiftlang/swift/pull/81415.
On creation, 'ClangImporter' adds overlay modulemap files for non-modular platform libraries (e.g. glibc, libstdc++), which allows Swift code to import and use those libraries.
This change adds the same filesystem overlay to dependency scanning queries by applying them to the filesystem instantiated for each depndency scanning worker. Without these overlays EBM builds cannot discover and use non-modular system libraries on non-Darwin platforms.
Resolves rdar://151780437
Use `resetBenignCodeGenOptions()` from clang dependency scanner to clear
the swift explicit module build cc1 arguments. This fixes the problem
that CurrentWorkingDirectory is leaking through
`-fcoverage-compilation-dir` that can cause extra module variants when
caching is enabled. This also avoid the duplicating the logics for
clearing CodeGen options inside Swift.
rdar://151395300
After removing the CASFS implementation for clang modules, there is no
need to capture clang extra file that sets up the VFS for the clang
modules since all content imported by ClangImporter is dependency
scanned and available via include-tree. This saves more ClangImporter
instance when caching is enabled.
Update the test to check that clang content found via `-Xcc` VFS options
can currently work without capture the headermaps and vfs overlays.
Using IncludeTree::FileList to concat the include tree file systems that
are passed on the command-line. This significantly reduce the
command-line size, and also makes the cache key computation a lot
faster.
rdar://148752988
This patch removes the `SWIFT_RETURNED_AS_RETAINED_BY_DEFAULT`
annotation while maintaining the support for
`SWIFT_RETURNED_AS_UNRETAINED_BY_DEFAULT`. These type-level annotations
were initially introduced in
[PR-81093](https://github.com/swiftlang/swift/pull/81093) to reduce the
annotation burden in large C++ codebases where many C++ APIs returning
`SWIFT_SHARED_REFERENCE` types are exposed to Swift.
### Motivation
The original goal was to make C++ interop more ergonomic by allowing
type-level defaults for ownership conventions
for`SWIFT_SHARED_REFERENCE` types . However, defaulting to retained
return values (+1) seems to be problematic and poses memory safety
risks.
### Why we’re removing `SWIFT_RETURNED_AS_RETAINED_BY_DEFAULT`
- **Memory safety risks:** Defaulting to retained can potentially lead
to use-after-free bugs when the API implementation actually returns
`unowned` (`+0`). These errors are subtle and can be hard to debug or
discover, particularly in the absence of explicit API-level
`SWIFT_RETURNS_(UN)RETAINED` annotations.
- **Risky transitive behavior:** If a `SWIFT_SHARED_REFERENCE` type is
annotated with `SWIFT_RETURNED_AS_RETAINED_BY_DEFAULT`, any new C++ API
returning this type will inherit the retained behavior by default—even
if the API's actual return behavior is unretained. Unless explicitly
overridden with `SWIFT_RETURNS_UNRETAINED`, this can introduce a silent
mismatch in ownership expectations and lead to use-after-free bugs. This
is especially risky in large or evolving codebases where such defaults
may be overlooked.
- **Simpler multiple inheritance semantics:** With only one type-level
default (`SWIFT_RETURNED_AS_UNRETAINED_BY_DEFAULT`), we avoid
complications that can arise when multiple base classes specify
conflicting ownership defaults. This simplifies reasoning about behavior
in class hierarchies and avoids ambiguity when Swift determines the
ownership convention for inherited APIs.
### Why we’re keeping `SWIFT_RETURNED_AS_UNRETAINED_BY_DEFAULT`
- It still enables projects to suppress warnings for unannotated C++
APIs returning `SWIFT_SHARED_REFERENCE` types, helping to reduce noise
while maintaining clarity.
- It encourages explicitness for retained behavior. Developers must
annotate retained return values with `SWIFT_RETURNS_RETAINED`, making
ownership intent clearer and safer.
- The worst-case outcome of assuming unretained when the return is
actually retained is a memory leak, which is more tolerable and easier
to debug than a use-after-free.
- Having a single default mechanism improves clarity for documentation,
diagnostics, and long-term maintenance of Swift/C++ interop code.
In Swift 6.1, we introduced `SWIFT_RETURNS_RETAINED` and
`SWIFT_RETURNS_UNRETAINED` annotations for C++ APIs to explicitly
specify the ownership convention of `SWIFT_SHARED_REFERENCE` type return
values.
Currently the Swift compiler emits warnings for unannotated C++ APIs
returning `SWIFT_SHARED_REFERENCE` types. We've received some feedback
that people are finding these warnings useful to get a reminder to
annotate their APIs. While this improves correctness , it also imposes a
high annotation burden on adopters — especially in large C++ codebases.
This patch addresses that burden by introducing two new type-level
annotations:
- `SWIFT_RETURNED_AS_RETAINED_BY_DEFAULT`
- `SWIFT_RETURNED_AS_UNRETAINED_BY_DEFAULT`
These annotations allow developers to specify a default ownership
convention for all C++ APIs returning a given
`SWIFT_SHARED_REFERENCE`-annotated type, unless explicitly overridden at
the API by using `SWIFT_RETURNS_RETAINED` or `SWIFT_RETURNS_UNRETAINED`.
If a C++ class inherits from a base class annotated with
`SWIFT_RETURNED_AS_RETAINED_BY_DEFAULT` or
`SWIFT_RETURNED_AS_UNRETAINED_BY_DEFAULT`, the derived class
automatically inherits the default ownership convention unless it is
explicitly overridden. This strikes a balance between safety/correctness
and usability:
- It avoids the need to annotate every API individually.
- It retains the ability to opt out of the default at the API level when
needed.
- To verify correctness, the user can just remove the
`SWIFT_RETURNED_AS_(UN)RETAINED_BY_DEFAULT` annotation from that type
and they will start seeing the warnings on all the unannotated C++ APIs
returning that `SWIFT_SHARED_REFERENCE` type. They can add
`SWIFT_RETURNS_(UN)RETAINED` annotation at each API in which they want a
different behaviour than the default. Then they can reintroduce the
`SWIFT_RETURNED_AS_(UN)RETAINED_BY_DEFAULT` at the type level to
suppress the warnings on remaining unannotated APIs.
A global default ownership convention (like always return
`unretained`/`unowned`) was considered but it would weaken the
diagnostic signal and remove valuable guardrails that help detect
use-after-free bugs and memory leaks in absence of
`SWIFT_RETURNS_(UN)RETAINED` annotations. In the absence of these
annotations when Swift emits the unannotated API warning, the current
fallback behavior (e.g. relying on heuristics based on API name such as
`"create"`, `"copy"`, `"get"`) is derived from Objective-C interop but
is ill-suited for C++, which has no consistent naming patterns for
ownership semantics.
Several codebases are expected to have project-specific conventions,
such as defaulting to unretained except for factory methods and
constructors. A type-level default seems like the most precise and
scalable mechanism to support such patterns. It integrates cleanly with
existing `SWIFT_SHARED_REFERENCE` usage and provides a per-type opt-in
mechanism without global silencing of ownership diagnostics.
This addition improves ergonomics while preserving the safety benefits
of explicit annotations and diagnostics.
rdar://145453509
Importing C++ class templates in symbolic mode has proven to be problematic in interaction with other compiler features, and it isn't used widely. This change removes the feature.
rdar://150528798
Similarly to how https://github.com/swiftlang/swift/pull/70564 configures 'ClangImporter's 'CodeGenerator' using Swift's compilation target triple, we must use the versioned version of the 'isWeakImported' query to determine linkage for imported Clang symbols.
It is possible for a C++ class template to inherit from a specialization
of itself. Normally, these are imported to Swift as separate (unrelated)
types, but when symbolic import is enabled, unspecialized templates are
imported in place of their specializations, leading to circularly
inheriting classes to seemingly inherit from themselves.
This patch adds a check to guard against the most common case of
circular inheritance, when a class template directly inherits from
itself. This pattern appears in a recent version of libc++,
necessitating this patch. However, the solution here is imperfect as it
does not handle more complex/contrived circular inheritance patterns.
This patch also adds a test case exercising this pattern. The
-index-store-path flag causes swift-frontend to index the C++ module
with symbolic import enabled, without the fix in this patch, that test
triggers an assertion failure due to the circular reference (and can
infinitely recurse in the StorageVisitor when assertions are disabled).
rdar://148026461
Currently, ClangImporter has some logic to pick the default arm64
target CPU (when -target-cpu isn't passed) based on the target OS
and arch variant.
This was originally done long ago in 3cf3f42e98, and later
maintained through 49a6c8eb7b, because it was necessary when
clang (targeting darwin) relied on -arch to set this sort of default.
Clang has migrated to full -target triples for a while now, and has
sophisticated logic for picking default target CPUs and features based
on the target triple.
Currently, we override that by passing our -mcpu explicitly.
Instead, allow clang to pick its defaults, and only pass -mcpu
when asked via -target-cpu.
This is visible in the test, with arm64 macOS now defaulting to M1.
The same applies to simulators, per Triple::isTargetMachineMac.
rdar://148377686
When serializing `@available` attributes, if the attribute applies to a custom
domain include enough information to deserialize the reference to that domain.
Resolves rdar://138441265.
Partially revert https://github.com/swiftlang/swift/pull/80035 now that Clang
has its own APIs for querying serialized modules for the decl representing the
availability domain with a given name.
To trigger this error one needs to import a nested type from C++, use it
in a generic context in Swift, and export it back to C++. We were
inconsisent in what namespace did we declare the functions to get the
type metadata for types. It was in the swift namespace for foreign types
and in the module namespace for Swift types. This PR standardizes on how
the metadata function is declared and called to fix the issue.
Fixes#80538.
rdar://148597079
When loading a module with embedded bridging header, bind the bridging
header module in the context when bridging header auto chaining is used.
This is because all the bridging header contents are chained into a PCH
file so binary module with bridging header should reference the PCH file
for all declarations.
rdar://148538787
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
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