When unconditionally casting from a base to a final derived class, e.g. `base as! Derived`, the program did not abort with a trap.
Instead the resulting null-pointer caused a crash later in the program.
This fix inserts a trap condition for the failing case of such a cast.
rdar://151462303
Raw identifiers are backtick-delimited identifiers that can contain any
non-identifier character other than the backtick itself, CR, LF, or other
non-printable ASCII code units, and which are also not composed entirely
of operator characters.
A `@convention(block)` closure in Swift is completely compatible with Objective-C
and does not need to be wrapped in a `__SwiftValue` box for use.
Previously, it was bridged verbatim when appearing by itself, but
could end up boxed when it went through array bridging.
The test verifies that:
* Objective-C does not see a `__SwiftValue` box
* Swift `type(of:)` does not see a `__SwiftValue` box
* Objective-C can actually call the closure
Resolves rdar://138132321
type(of:) now returns the dynamic type of the contents of
an extended existential (just like it does for a regular existential)
Mirror can now reflect fields of a value stored inside an extended
existential (just like it can with a regular existential). This
requires type(of:) support, since Mirror internals use that to
determine how to reflect a value.
Resolves rdar://102906195
These tests are testing changes that aren't present in older runtimes:
test/stdlib/SwiftValueNSObject.swift
test/stdlib/SwiftObjectNSObject.swift
test/stdlib/BridgeEquatableToObjC.swift
And this test looks for some wording that's different on older runtimes. This one already does availability checks, so we change the requirements to SwiftStdlib 5.11:
test/Casting/CastTraps.swift.gyb
Given this
```
@objc protocol P { func f() }
class C: P { func f() {} }
```
the casts `C.self is any P` and `C.self as? any P` should always fail,
because the metatype of `C.self` does not have an `f()` implementation.
These casts previously succeeded because the runtime implementation
deferred to Obj-C's `[o conformsToProtocol:p]`, and that behaves
differently depending on whether `o` is a class instance or
a Class itself.
Since these casts should never succeed, I've just modified the
Swift runtime logic to fail whenever the source of the cast
is an Obj-C Class and the target is a protocol existential.
Resolves: rdar://106973771
The following sequence of casts would previously succeed
```
struct S {}
let s = S() as AnyObject
s as? NSObject
```
The final cast here should fail, since `S` clearly is not a
subclass of NSObject. But it would previously succeed because
the `as AnyObject` would package the struct into an ObjC-compatible
`__SwiftValue` class. This latter is an NSObject subclass.
This bug was fixed in the main `swift_dynamicCast` runtime function
some time ago, but not in the `swift_dynamicCastObjCClass` which
is chosen by IRGen to optimize casts to ObjC class types.
This PR changes the latter to test for `__SwiftValue` and fall
back to the former in that case in order to get the correct
handling. Falling back to `swift_dynamicCast` also ensures that
the contents of the `__SwiftValue` are correctly unwrapped/bridged/etc
as necessary to fully support Swift casting semantics.
Resolves: rdar://111422725
TODO: I've left an XFAILed test here about the behavior of `type(of:)`
with `__SwiftValue` boxes.
`module.map` as a module map name has been discouraged since 2014, and
Clang will soon warn on its usage. This patch renames all instances of
`module.map` in the Swift tests to `module.modulemap` in preparation
for this change to Clang.
rdar://106123303
* [IRGen] Make pointers to accessor functions in layout strings relative
rdar://106319336
Pointers embedded in static layout strings should always be relative, so layout strings can reside in read-only memory.
* Properly handle reference storage ownership
* Pass layout tag and metadata / type layout ppointers separately
* Layout string instantiation fully working
* Fix cases where hasLayoutString flag was not set when it should have
* Update include/swift/ABI/Metadata.h
To allow for better compiler optimizations, the
runtime should guarantee that AnyHashable does
not get boxed unnecessarily.
In particular, there was a concern that casting
an `AnyHashable` containing a class reference
to `AnyObject` would box the AnyHashable instead
of unwrapping it.
Further testing shows that the runtime is NOT
doing this unnecessary boxing at current.
Resolves rdar://90269352
This PR changes the casting machinery to avoid casting `__SwiftValue` boxes
directly. This forces the caster to instead unwrap `__SwiftValue` boxes and
retry with the inner content. This results in boxed values being cast like the
inner content.
This fixes the behavior in situations like the following:
```
let t = ...
let s = t as Any as! AnyObject
// `s` is now a `__SwiftValue` box
// Next line should be true iff t conforms to NSCopying
// Prior to this change, it always succeeds
s is NSCopying
```
After this change, the above cast succeeds only if `t` actually
conforms to `NSCopying`.
This is a follow-on to PR#37683.
Related to: SR-14635
Pass the correct type to `emitHeapMetadataRefForHeapObject()`.
Fixes a runtime crash in case a class protocol is cast to a final swift class, where the actual object is an ObjectiveC class instance.
rdar://99626888
The fix here is two-fold:
1) Teach SILGen that it cannot use the scalar casting paths for extended existentials
2) Teach the runtime casting entrypoint to unwrap as much metatype structure as possible
before arriving at a 'Self' type bound for the requirement checking paths.
The code here mirrors the destructuring check we're doing in remote mirrors.
rdar://95166916
Implement casting to and from extended existentials. This is done by slightly generalizing the conditional conformances checking infrastructure.
Unfortunately, casts for reference types and metatypes are unsound because IRGen is peepholing all non-opaque existential conversions with a helper. I’ll disable that in a follow-up.
rdar://92197049
When casting a class instance to a final class, we can directly compare the isa-pointer with address of the metadata.
This avoids a call to `swift_dynamicCastClass`.
It also avoids a call to the metadata accessor of the class (which calls `swift_getInitializedObjCClass`).
For comparing the metadata pointers it's not required that the metadata is fully initialized.
* Refactor Bincompat
Organize everything around internal functions that test for
a particular OS version.
Correctly handle cases where we don't know the version of the app.
Make all bincompat functions consistently return `true` for the
legacy semantics, `false` for new semantics. Consistently name
them all to reflect this.
* Conditionalize the support for SR-14635
SR-14635 pointed out a hole in the updated dynamic casting logic
that allowed certain casts that should have been illegal.
In particular, when casting certain types to Obj-C protocols,
the Swift value gets boxed; we would permit the cast to succeed
whenever the resulting box satisfied the protocol. For example,
this allowed any Swift value to be cast to `NSCopying` regardless of
whether or not it implemented the required `copy(with:)` method.
This was fixed in #37683 to reject such casts but of course some folks were
depending on this behavior to pass Swift data into Obj-C functions.
(The properly supported approach for passing arbitrary Swift data into
Obj-C functions is to cast the Swift value to `AnyObject`.)
This change makes that new behavior conditional. For now,
the legacy semantics are enabled on Apple platforms and the
new semantics are in use everywhere else. This will allow
us to gradually enable enforcement of the new behavior over
time.
* Just skip this test on Apple platforms, since it is inconsistently implemented there (and is therefore not really testable)
tryGetCompleteMetadataNonblocking crashes on artificial subclasses due to the NULL type descriptor. Explicitly check for artificial subclasses in getSuperclassForMaybeIncompleteMetadata and immediately return their Superclass field. Artificial subclasses are always fully initialized so we don't need to do anything special for them.
rdar://72583931