mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
IRGen: fix how metadata is loaded for fast class casting
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
This commit is contained in:
@@ -1108,7 +1108,7 @@ llvm::Value *irgen::emitFastClassCastIfPossible(IRGenFunction &IGF,
|
||||
|
||||
// Load the isa pointer.
|
||||
llvm::Value *objMetadata = emitHeapMetadataRefForHeapObject(IGF, instance,
|
||||
targetFormalType, GenericSignature(), /*suppress cast*/ true);
|
||||
sourceFormalType, GenericSignature(), /*suppress cast*/ true);
|
||||
llvm::Value *rhs = IGF.Builder.CreateBitCast(objMetadata, IGF.IGM.Int8PtrTy);
|
||||
|
||||
// return isa_ptr == metadata_ptr ? instance : nullptr
|
||||
|
||||
@@ -1917,7 +1917,8 @@ llvm::Value *irgen::emitHeapMetadataRefForHeapObject(IRGenFunction &IGF,
|
||||
GenericSignature sig,
|
||||
bool suppressCast) {
|
||||
ClassDecl *theClass = objectType.getClassOrBoundGenericClass();
|
||||
if (theClass && isKnownNotTaggedPointer(IGF.IGM, theClass)) {
|
||||
if ((theClass && isKnownNotTaggedPointer(IGF.IGM, theClass)) ||
|
||||
!IGF.IGM.ObjCInterop) {
|
||||
auto isaEncoding = getIsaEncodingForType(IGF.IGM, objectType, sig);
|
||||
return emitLoadOfHeapMetadataRef(IGF, object,
|
||||
isaEncoding,
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
// 2. check if the generated IR looks like expected:
|
||||
|
||||
// RUN: %target-swift-frontend -module-name=Main -I%t %s -emit-ir -g -o - | %FileCheck %s
|
||||
// RUN: %target-swift-frontend -module-name=Main -I%t %s -emit-ir -g -o - | %FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-%target-objc-interop
|
||||
|
||||
// REQUIRES: executable_test
|
||||
|
||||
@@ -48,6 +48,7 @@ func castToFinal(_ b: Classes.Base) -> Classes.Final? {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define {{.*}} @"$s4Main24unconditionalCastToFinaly7Classes0E0CAC4BaseCF"
|
||||
// CHECK-NOT: call {{.*}}@object_getClass
|
||||
// CHECK-NOT: @swift_dynamicCastClass
|
||||
// CHECK: }
|
||||
@inline(never)
|
||||
@@ -64,6 +65,8 @@ func castToResilientFinal(_ b: ResilientClasses.Base) -> ResilientClasses.Final?
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define {{.*}} @"$s4Main19castProtocolToFinaly7Classes0E0CSgAC1P_pF"
|
||||
// CHECK-objc: call {{.*}}@object_getClass
|
||||
// CHECK-nonobjc: load
|
||||
// CHECK-NOT: @swift_dynamicCastClass
|
||||
// CHECK: }
|
||||
@inline(never)
|
||||
|
||||
Reference in New Issue
Block a user