The runtime logic for printing a foreign reference type is behind `if #available(SwiftStdlib 6.2, *)`, which means it won't run on older versions of macOS, even if you use a newer Swift runtime.
rdar://153735437
(cherry picked from commit a292113ef2)
848fad00 introduced support for printing foreign reference types. It changes both the compiler and the runtime, and having the runtime change applied is required for the test to pass. Let's not try to run it with an old runtime.
This change also splits up a test for printing of value types from a test for printing of foreign reference types, since we don't have any runtime restrictions for value types.
rdar://153205860
(cherry picked from commit 62d56067c8)
Immortal C++ foreign reference types get TrivialTypeLowering instead of ReferenceTypeLowering, since they do not have retain/release lifetime operations. This was tripping up an assertion in SILVerifier.
rdar://147251759 / resolves https://github.com/swiftlang/swift/issues/80065
(cherry picked from commit 2e3df1c0f3)
**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.
The warnings that ClangImporter emits about issues it encounters while
importing declarations from Clang modules should all belong to a diagnostic
group so that users of `-warnings-as-errors` can control their behavior using
the compiler flags introduce with SE-0443. It's especially important that these
diagnostics be controllable since they are often caused by external
dependencies and therefore the developer may not have any control over whether
they are emitted.
The `#ClangDeclarationImport` diagnostic group is intentionally broad so that
developers have a way to control all of these diagnostics with a single
`-Wwarning` flag. I fully expect that we'll introduce finer-grained diagnostic
groups for some of these diagnostics in the future, but those groups should be
hierarchically nested under `#ClangDeclarationImport`, which is supported by
SE-0443.
Resolves rdar://150524204.
Explanation: There was an inconsistency between non-const and const FRT
pointers. The former used Direct_Unowned the latter used Indirect
calling convention. We want to use Direct_Unowned for both cases. The
crash was the result of a calling convention mismatch between the
SILFunctionType of a Swift closure and the SILFunctionType of the C++
function's formal parameter that is taking a function pointer. The
compiler tried to insert a conversion between the two function types
that does not exist and caused an assertion in debug compilers and
miscompilation in production compilers.
Issue: rdar://149398905
Risk: Low, the fix is targeted and we change to a well-tested behavior
with non-const FRT pointers.
Testing: Regression test added.
Original PR: #81070
Reviewer: @j-hui
We should not complain about usage of SWIFT_RETURNS_(UN)RETAINED for templated C++ APIs when instantiated with a non SWIFT_SHARED_REFERENCE types
rdar://143732201
Explanation: Fixes that functions imported from C++ namespaces are
taking a different code path than functions importing from the global
namespace. This also fixes an error where the return type of a templated
function is sometimes not imported.
Scope: C++ forward interop.
Issue: rdar://148735986
Risk: Low, the fix is targeted to make C++ functions in namespaces take
a well tested code path that we already use for C++ functions in the
global scope.
Testing: Added tests to test suite
Reviewer: John Hui
This is a follow-up to d3e43bbe which resolved the issue for value types, but not for foreign reference types.
This change teaches IRGen that a base type of a C++ type might occupy less memory than its `sizeof`, specifically, it might only use `dsize` amount of memory.
rdar://147527755
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
This PR adds a feature to import static factory functions returning
foreign reference types to be imported as initializers using the
SWIFT_NAME annotation.
It turns out the query to check the reference semantics of a type had
the side effect of importing some functions/types. This could introduce
circular reference errors with our queries. This PR removes this side
effect from the query and updates the test files. Since we do the same
work later on in another query, the main change is just the wording of
the diagnostics (and we now can also infer immortal references based on
the base types). This PR also reorders some operations, specifically now
we mark base classes as imported before we attempt to import template
arguments.
After these changes it is possible to remove the last feature check for
strict memory safe mode. We want to mark types as @unsafe in both
language modes so we can diagnose redundant unsafe markers even when the
feature is off.
PredictableMemoryAccessOptimizations has become unmaintainable as-is.
RedundantLoadElimination does (almost) the same thing as PredictableMemoryAccessOptimizations.
It's not as powerful but good enough because PredictableMemoryAccessOptimizations is actually only needed for promoting integer values for mandatory constant propagation.
And most importantly: RedundantLoadElimination does not insert additional copies which was a big problem in PredictableMemoryAccessOptimizations.
Fixes rdar://142814676
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
When a C++ foreign reference type is conformed to a Swift protocol via a Swift extension, trying to cast `any MyProtocol` to the foreign reference type crashes the runtime.
This was because `selectCasterForDest` wasn't handling C++ foreign reference types, and we were hitting `swift_unreachable`.
This change makes sure the runtime doesn't crash for such casts.
Notably, Swift doesn't have enough metadata to determine if the conditional cast actually succeeded. This is also a problem for CF types. Casting CF types in a similar fashion triggers a typechecker diagnostic. That diagnostic will be amended in a follow-up patch to also trigger for foreign reference types.
rdar://141227849
In C++, a primary base class that is placed in the beginning of the type's memory layout isn't always the type that is the first in the list of bases – the base types might be laid out in memory in a different order.
This makes sure that IRGen handles base types of C++ structs in the correct order.
This fixes an assertion in asserts-enabled compilers, and an out-of-memory error in asserts-disabled compilers. The issue was happening for both value types and foreign reference types. This change also includes a small refactoring to reuse the logic between the two code paths.
rdar://140848603
`assert`s get stripped away in release builds. To make sure the checks in tests still run in release builds, this switches to `expectTrue`/`expectFalse` instead of `assert`.
Many existing C APIs for retaining references, including Apple's own, return
the reference. Support this pattern, along with the existing void return
signature, with when importing reference types from C++.
Type annotations for instruction operands are omitted, e.g.
```
%3 = struct $S(%1, %2)
```
Operand types are redundant anyway and were only used for sanity checking in the SIL parser.
But: operand types _are_ printed if the definition of the operand value was not printed yet.
This happens:
* if the block with the definition appears after the block where the operand's instruction is located
* if a block or instruction is printed in isolation, e.g. in a debugger
The old behavior can be restored with `-Xllvm -sil-print-types`.
This option is added to many existing test files which check for operand types in their check-lines.
For types imported from C++, the original clang::TypeDecl is saved in
the swift::Type and reused for conversions back to clang::QualType.
However, the conversion did not account for foreign reference types,
which should be mapped to a pointer to the C++ record type, rather than
the record type itself.
This bug first appeared as a function template instantiation failure
due to a sanity check performed by SwiftDeclConverter::foreignReferenceTypePassedByRef()
but may also affect other round-tripping type conversions.
The added test case demonstrates the template instantiation scenario,
where templates were being used to overcome Swift/C++ interop's current
lack of support for class inheritance.
rdar://134979343
C++ foreign reference types have custom reference counting mechanisms, so they cannot conform to `AnyObject`.
Currently Swift's type system treats C++ FRTs as `AnyObject`s on non-Darwin platforms, which is incorrect. This change makes sure the behavior is consistent with Darwin platform, i.e. a cast of C++ FRT to `AnyObject` is rejected by the typechecker.
rdar://136664617
This fixes a runtime crash that occurs when a pointer to a foreign
reference type is passed to objc_retainAutoreleasedReturnValue.
This reverts 335cec0e8d.
rdar://117353222