Merge pull request #12632 from DougGregor/suppress-eager-init-nscoding-availability-4.0
Suppress inference of @_staticInitializeObjCMetadata for "newer" classes
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 88c5771..2c0b9e4 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -6059,7 +6059,8 @@
/// Infer the attribute tostatic-initialize the Objective-C metadata for the
/// given class, if needed.
-static void inferStaticInitializeObjCMetadata(ClassDecl *classDecl) {
+static void inferStaticInitializeObjCMetadata(TypeChecker &tc,
+ ClassDecl *classDecl) {
// If we already have the attribute, there's nothing to do.
if (classDecl->getAttrs().hasAttribute<StaticInitializeObjCMetadataAttr>())
return;
@@ -6071,6 +6072,22 @@
return;
}
+ // If this class isn't always available on the deployment target, don't
+ // mark it as statically initialized.
+ // FIXME: This is a workaround. The proper solution is for IRGen to
+ // only statically initializae the Objective-C metadata when running on
+ // a new-enough OS.
+ if (auto sourceFile = classDecl->getParentSourceFile()) {
+ AvailabilityContext availableInfo = AvailabilityContext::alwaysAvailable();
+ for (Decl *enclosingDecl = classDecl; enclosingDecl;
+ enclosingDecl = enclosingDecl->getDeclContext()
+ ->getInnermostDeclarationDeclContext()) {
+ if (!tc.isDeclAvailable(enclosingDecl, SourceLoc(), sourceFile,
+ availableInfo))
+ return;
+ }
+ }
+
// Infer @_staticInitializeObjCMetadata.
ASTContext &ctx = classDecl->getASTContext();
classDecl->getAttrs().add(
@@ -6188,7 +6205,7 @@
}
// Infer @_staticInitializeObjCMetadata if needed.
- inferStaticInitializeObjCMetadata(classDecl);
+ inferStaticInitializeObjCMetadata(*this, classDecl);
}
}
}
diff --git a/test/decl/protocol/conforms/nscoding_availability_osx.swift b/test/decl/protocol/conforms/nscoding_availability_osx.swift
new file mode 100644
index 0000000..b9720cd
--- /dev/null
+++ b/test/decl/protocol/conforms/nscoding_availability_osx.swift
@@ -0,0 +1,22 @@
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -parse-as-library -swift-version 4 %s -target x86_64-apple-macosx10.11 -verify
+
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -parse-as-library -swift-version 4 %s -target x86_64-apple-macosx10.11 -dump-ast 2> %t.ast
+// RUN: %FileCheck %s < %t.ast
+
+// REQUIRES: objc_interop
+// REQUIRES: OS=macosx
+
+import Foundation
+
+// Nested classes that aren't available in our deployment target.
+@available(OSX 10.12, *)
+class CodingI : NSObject, NSCoding {
+ required init(coder: NSCoder) { }
+ func encode(coder: NSCoder) { }
+}
+
+@available(OSX 10.12, *)
+class OuterCodingJ {
+ // CHECK-NOT: class_decl "NestedJ"{{.*}}@_staticInitializeObjCMetadata
+ class NestedJ : CodingI { }
+}