Skip to content

Commit b4ca11e

Browse files
authored
Merge pull request #78238 from swiftlang/egorzhdan/6.1-frt-as-existential-crash
🍒[cxx-interop] Fix runtime crash when casting from an existential to a foreign reference type
2 parents 8e4cfa3 + a81a7e4 commit b4ca11e

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

stdlib/public/runtime/DynamicCast.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,16 @@ tryCastToForeignClass(
591591
return DynamicCastResult::Failure;
592592
}
593593

594+
static DynamicCastResult tryCastToForeignReferenceType(
595+
OpaqueValue *destLocation, const Metadata *destType, OpaqueValue *srcValue,
596+
const Metadata *srcType, const Metadata *&destFailureType,
597+
const Metadata *&srcFailureType, bool takeOnSuccess, bool mayDeferChecks) {
598+
assert(srcType != destType);
599+
assert(destType->getKind() == MetadataKind::ForeignReferenceType);
600+
601+
return DynamicCastResult::Failure;
602+
}
603+
594604
/******************************************************************************/
595605
/***************************** Enum Destination *******************************/
596606
/******************************************************************************/
@@ -2187,6 +2197,8 @@ static tryCastFunctionType *selectCasterForDest(const Metadata *destType) {
21872197
return tryCastToOptional;
21882198
case MetadataKind::ForeignClass:
21892199
return tryCastToForeignClass;
2200+
case MetadataKind::ForeignReferenceType:
2201+
return tryCastToForeignReferenceType;
21902202
case MetadataKind::Opaque:
21912203
return tryCastToOpaque;
21922204
case MetadataKind::Tuple:

test/Interop/Cxx/foreign-reference/witness-table.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,15 @@ WitnessTableTestSuite.test("As a Sequence") {
6161
expectEqual(count, 3)
6262
}
6363

64+
WitnessTableTestSuite.test("As an existential") {
65+
let existential: any ListNode = makeLinkedList()
66+
let cast: CxxLinkedList? = existential as? CxxLinkedList
67+
expectNotNil(cast)
68+
expectEqual(cast?.value, 0)
69+
expectEqual(cast?.next()?.value, 1)
70+
expectEqual(cast?.next()?.next()?.value, 2)
71+
}
72+
6473
}
6574

6675
runAllTests()

0 commit comments

Comments
 (0)