Skip to content

Commit 9cffd45

Browse files
committed
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.
1 parent 503d83a commit 9cffd45

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,17 @@ SerializedKind_t SILDeclRef::getSerializedKind() const {
856856
// marked as @frozen.
857857
if (isStoredPropertyInitializer() || (isPropertyWrapperBackingInitializer() &&
858858
d->getDeclContext()->isTypeContext())) {
859-
auto *nominal = cast<NominalTypeDecl>(d->getDeclContext()->getImplementedObjCContext());
859+
auto *nominal = dyn_cast<NominalTypeDecl>(d->getDeclContext());
860+
861+
// If this isn't in a nominal, it must be in an @objc @implementation
862+
// extension. We don't serialize those since clients outside the module
863+
// don't think of these as Swift classes.
864+
if (!nominal) {
865+
ASSERT(isa<ExtensionDecl>(d->getDeclContext()) &&
866+
cast<ExtensionDecl>(d->getDeclContext())->isObjCImplementation());
867+
return IsNotSerialized;
868+
}
869+
860870
auto scope =
861871
nominal->getFormalAccessScope(/*useDC=*/nullptr,
862872
/*treatUsableFromInlineAsPublic=*/true);

test/SILGen/Inputs/objc_implementation.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,12 @@ NS_ASSUME_NONNULL_BEGIN
99

1010
@end
1111

12+
@interface Rdar114874429 : NSObject
13+
14+
- (instancetype)init;
15+
16+
@property (readonly) NSInteger prop;
17+
18+
@end
19+
1220
NS_ASSUME_NONNULL_END

test/SILGen/objc_implementation.swift

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
// 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
1+
// RUN: %target-swift-frontend -emit-silgen -import-objc-header %S/Inputs/objc_implementation.h -swift-version 5 %s -target %target-stable-abi-triple > %t
2+
// RUN: %FileCheck --input-file %t %s
3+
// RUN: %FileCheck --input-file %t --check-prefix NEGATIVE %s
24

35
// REQUIRES: objc_interop
46

@@ -11,3 +13,17 @@
1113
// CHECK: function_ref @$ss25_unimplementedInitializer9className04initD04file4line6columns5NeverOs12StaticStringV_A2JS2utF
1214
// CHECK: } // end sil function '$sSo9ImplClassC19objc_implementationEABycfc'
1315
}
16+
17+
//
18+
// objcImpl class with an initial value expression referencing a nonpublic
19+
// function (rdar://114874429)
20+
//
21+
22+
internal func internalFunc() -> Int { 42 }
23+
24+
@objc @implementation extension Rdar114874429 {
25+
let prop: Int = internalFunc()
26+
27+
// CHECK-LABEL : sil{{.*}}@$sSo13Rdar114874429C19objc_implementationE4propSivpfi :
28+
// NEGATIVE-NOT: sil{{.*}} [serialized] {{.*}}@$sSo13Rdar114874429C19objc_implementationE4propSivpfi :
29+
}

0 commit comments

Comments
 (0)