mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[PrintAsObjC] Attempt at fixing SR-5018: marking +new unavailable when -init is unavailable.
Currently a loop-hole exists by which one could end up invoking an unavailable -init initializer from Obj-C when it is unavailable by using +new (which itself calls -init) https://bugs.swift.org/browse/SR-5018
This commit is contained in:
@@ -604,6 +604,7 @@ private:
|
||||
}
|
||||
|
||||
bool skipAvailability = false;
|
||||
bool makeNewUnavailable = false;
|
||||
// Swift designated initializers are Objective-C designated initializers.
|
||||
if (auto ctor = dyn_cast<ConstructorDecl>(AFD)) {
|
||||
if (ctor->hasStubImplementation()
|
||||
@@ -612,6 +613,9 @@ private:
|
||||
// required access
|
||||
os << " SWIFT_UNAVAILABLE";
|
||||
skipAvailability = true;
|
||||
// If -init is unavailable, then +new should be, too:
|
||||
const bool selectorIsInit = selectorPieces.getNumArgs() == 0 && selectorPieces.front().str() == "init";
|
||||
makeNewUnavailable = selectorIsInit;
|
||||
} else if (ctor->isDesignatedInit() &&
|
||||
!isa<ProtocolDecl>(ctor->getDeclContext())) {
|
||||
os << " OBJC_DESIGNATED_INITIALIZER";
|
||||
@@ -643,6 +647,10 @@ private:
|
||||
}
|
||||
|
||||
os << ";\n";
|
||||
|
||||
if (makeNewUnavailable) {
|
||||
os << "+ (nonnull instancetype)new SWIFT_UNAVAILABLE;\n";
|
||||
}
|
||||
}
|
||||
|
||||
void printAbstractFunctionAsFunction(FuncDecl *FD) {
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
|
||||
// CHECK-LABEL: @interface AvailabilitySub
|
||||
// CHECK-NEXT: - (nonnull instancetype)init SWIFT_UNAVAILABLE;
|
||||
// CHECK-NEXT: + (nonnull instancetype)new SWIFT_UNAVAILABLE;
|
||||
// CHECK-NEXT: - (nonnull instancetype)initWithX:(NSInteger)_ SWIFT_UNAVAILABLE;
|
||||
// CHECK-NEXT: @end
|
||||
|
||||
|
||||
@@ -175,6 +175,15 @@ class DiscardableResult : NSObject {
|
||||
@objc init(evenMoreFun: ()) { super.init() }
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @interface InheritedInitializersRequired
|
||||
// CHECK-NEXT: - (nonnull instancetype)initWithEvenMoreFun OBJC_DESIGNATED_INITIALIZER;
|
||||
// CHECK-NEXT: - (nonnull instancetype)init SWIFT_UNAVAILABLE;
|
||||
// CHECK-NEXT: + (nonnull instancetype)new SWIFT_UNAVAILABLE;
|
||||
// CHECK-NEXT: @end
|
||||
@objc class InheritedInitializersRequired : InheritedInitializers {
|
||||
@objc required init(evenMoreFun: ()) { super.init() }
|
||||
}
|
||||
|
||||
// NEGATIVE-NOT: NotObjC
|
||||
class NotObjC {}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ protocol CustomNameType2 {}
|
||||
// CHECK-LABEL: @interface MyObject : NSObject <NSCoding, Fungible>
|
||||
// CHECK-NEXT: initWithCoder
|
||||
// CHECK-NEXT: init SWIFT_UNAVAILABLE
|
||||
// CHECK-NEXT: new SWIFT_UNAVAILABLE
|
||||
// CHECK-NEXT: @end
|
||||
// NEGATIVE-NOT: @protocol NSCoding
|
||||
class MyObject : NSObject, NSCoding, Fungible {
|
||||
|
||||
Reference in New Issue
Block a user