Fix objcImpl SILGen crash with initial value

The initial value expressions of stored properties in objcImpl classes were being incorrectly marked as serializable. As a result, the compiler would crash with a SIL verification failure if one of them called a non-public function or initializer.

Fix this problem by not marking these initial value expression functions as serializable. Code in other modules should not call them anyway, since they think of the class as a pure ObjC class.

Fixes rdar://114874429.
This commit is contained in:
Becca Royal-Gordon
2024-07-23 16:13:51 -07:00
parent 503d83a861
commit 9cffd4528d
3 changed files with 36 additions and 2 deletions

View File

@@ -856,7 +856,17 @@ SerializedKind_t SILDeclRef::getSerializedKind() const {
// marked as @frozen.
if (isStoredPropertyInitializer() || (isPropertyWrapperBackingInitializer() &&
d->getDeclContext()->isTypeContext())) {
auto *nominal = cast<NominalTypeDecl>(d->getDeclContext()->getImplementedObjCContext());
auto *nominal = dyn_cast<NominalTypeDecl>(d->getDeclContext());
// If this isn't in a nominal, it must be in an @objc @implementation
// extension. We don't serialize those since clients outside the module
// don't think of these as Swift classes.
if (!nominal) {
ASSERT(isa<ExtensionDecl>(d->getDeclContext()) &&
cast<ExtensionDecl>(d->getDeclContext())->isObjCImplementation());
return IsNotSerialized;
}
auto scope =
nominal->getFormalAccessScope(/*useDC=*/nullptr,
/*treatUsableFromInlineAsPublic=*/true);

View File

@@ -9,4 +9,12 @@ NS_ASSUME_NONNULL_BEGIN
@end
@interface Rdar114874429 : NSObject
- (instancetype)init;
@property (readonly) NSInteger prop;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,4 +1,6 @@
// RUN: %target-swift-frontend -emit-silgen -import-objc-header %S/Inputs/objc_implementation.h -swift-version 5 %s -target %target-stable-abi-triple | %FileCheck %s
// RUN: %target-swift-frontend -emit-silgen -import-objc-header %S/Inputs/objc_implementation.h -swift-version 5 %s -target %target-stable-abi-triple > %t
// RUN: %FileCheck --input-file %t %s
// RUN: %FileCheck --input-file %t --check-prefix NEGATIVE %s
// REQUIRES: objc_interop
@@ -11,3 +13,17 @@
// CHECK: function_ref @$ss25_unimplementedInitializer9className04initD04file4line6columns5NeverOs12StaticStringV_A2JS2utF
// CHECK: } // end sil function '$sSo9ImplClassC19objc_implementationEABycfc'
}
//
// objcImpl class with an initial value expression referencing a nonpublic
// function (rdar://114874429)
//
internal func internalFunc() -> Int { 42 }
@objc @implementation extension Rdar114874429 {
let prop: Int = internalFunc()
// CHECK-LABEL : sil{{.*}}@$sSo13Rdar114874429C19objc_implementationE4propSivpfi :
// NEGATIVE-NOT: sil{{.*}} [serialized] {{.*}}@$sSo13Rdar114874429C19objc_implementationE4propSivpfi :
}